# packages

pkgId: b66b4cd4c56ee7200826b1a2c777a90349e0696e75775f9505b8c30bd4bf9999
name: rh-python36-certifi
arch: noarch
version: 2019.11.28
epoch: 0
release: 1
summary: Python package for providing Mozilla's CA Bundle.
url: http://certifi.io/
rpm_license: MPL-2.0
rpm_vendor: Kenneth Reitz <me@kennethreitz.com>
rpm_group: Development/Libraries
rpm_buildhost: d92c5217cc8346efa1837d420a500bed
rpm_sourcerpm: rh-python36-certifi-2019.11.28-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01120307-rh-python36-certifi/rh-python36-certifi-2019.11.28-1.noarch.rpm
checksum_type: sha256
description:
  Certifi: Python SSL Certificates
  ================================

  `Certifi`_ is a carefully curated collection of Root Certificates for
  validating the trustworthiness of SSL certificates while verifying the identity
  of TLS hosts. It has been extracted from the `Requests`_ project.

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

  ``certifi`` is available on PyPI. Simply install it with ``pip``::

      $ pip install certifi

  Usage
  -----

  To reference the installed certificate authority (CA) bundle, you can use the
  built-in function::

      >>> import certifi

      >>> certifi.where()
      '/usr/local/lib/python2.7/site-packages/certifi/cacert.pem'

  Enjoy!

  1024-bit Root Certificates
  ~~~~~~~~~~~~~~~~~~~~~~~~~~

  Browsers and certificate authorities have concluded that 1024-bit keys are
  unacceptably weak for certificates, particularly root certificates. For this
  reason, Mozilla has removed any weak (i.e. 1024-bit key) certificate from its
  bundle, replacing it with an equivalent strong (i.e. 2048-bit or greater key)
  certificate from the same CA. Because Mozilla removed these certificates from
  its bundle, ``certifi`` removed them as well.

  In previous versions, ``certifi`` provided the ``certifi.old_where()`` function
  to intentionally re-add the 1024-bit roots back into your bundle. This was not
  recommended in production and therefore was removed. To assist in migrating old
  code, the function ``certifi.old_where()`` continues to exist as an alias of
  ``certifi.where()``. Please update your code to use ``certifi.where()``
  instead. ``certifi.old_where()`` will be removed in 2018.

  .. _`Certifi`: http://certifi.io/en/latest/
  .. _`Requests`: http://docs.python-requests.org/en/latest/


pkgId: 85b3b0a2ef964ce0c4dc484e21946c97eab26f28d9604d61ffff17b97e99c9a5
name: rh-python36-cffi
arch: ppc64le
version: 1.14.0
epoch: 0
release: 1
summary: Foreign Function Interface for Python calling C code.
url: http://cffi.readthedocs.org
rpm_license: MIT
rpm_vendor: Armin Rigo, Maciej Fijalkowski <python-cffi@googlegroups.com>
rpm_group: Development/Libraries
rpm_buildhost: 61e74e4c00bf4f768d47b66b825235e0
rpm_sourcerpm: rh-python36-cffi-1.14.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01225012-rh-python36-cffi/rh-python36-cffi-1.14.0-1.ppc64le.rpm
checksum_type: sha256
description:
  CFFI
  ====

  Foreign Function Interface for Python calling C code.
  Please see the `Documentation <http://cffi.readthedocs.org/>`_.

  Contact
  -------

  `Mailing list <https://groups.google.com/forum/#!forum/python-cffi>`_


pkgId: 08cc6199da18b65aa69795de869c3fe1030fd07d47c055ec95e726aa9b20b038
name: rh-python36-cffi-debuginfo
arch: ppc64le
version: 1.14.0
epoch: 0
release: 1
summary: Debug information for package rh-python36-cffi
url: http://cffi.readthedocs.org
rpm_license: MIT
rpm_vendor: Armin Rigo, Maciej Fijalkowski <python-cffi@googlegroups.com>
rpm_group: Development/Debug
rpm_buildhost: 61e74e4c00bf4f768d47b66b825235e0
rpm_sourcerpm: rh-python36-cffi-1.14.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01225012-rh-python36-cffi/rh-python36-cffi-debuginfo-1.14.0-1.ppc64le.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-cffi.
  Debug information is useful when developing applications that use this
  package or when debugging this package.


pkgId: 5eaa9687ab13398de3588194063b7fa39cbc0248939eb232197d488cb9a72748
name: rh-python36-chardet
arch: noarch
version: 3.0.4
epoch: 0
release: 1
summary: Universal encoding detector for Python 2 and 3
url: https://github.com/chardet/chardet
rpm_license: LGPL
rpm_vendor: Daniel Blanchard <dan.blanchard@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: 2e2eb1929cf44e56b4e3c1d406c835ce
rpm_sourcerpm: rh-python36-chardet-3.0.4-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00878995-rh-python36-chardet/rh-python36-chardet-3.0.4-1.noarch.rpm
checksum_type: sha256
description:
  Chardet: The Universal Character Encoding Detector
  --------------------------------------------------

  .. image:: https://img.shields.io/travis/chardet/chardet/stable.svg
     :alt: Build status
     :target: https://travis-ci.org/chardet/chardet

  .. image:: https://img.shields.io/coveralls/chardet/chardet/stable.svg
     :target: https://coveralls.io/r/chardet/chardet

  .. image:: https://img.shields.io/pypi/v/chardet.svg
     :target: https://warehouse.python.org/project/chardet/
     :alt: Latest version on PyPI

  .. image:: https://img.shields.io/pypi/l/chardet.svg
     :alt: License


  Detects
   - ASCII, UTF-8, UTF-16 (2 variants), UTF-32 (4 variants)
   - Big5, GB2312, EUC-TW, HZ-GB-2312, ISO-2022-CN (Traditional and Simplified Chinese)
   - EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP (Japanese)
   - EUC-KR, ISO-2022-KR (Korean)
   - KOI8-R, MacCyrillic, IBM855, IBM866, ISO-8859-5, windows-1251 (Cyrillic)
   - ISO-8859-5, windows-1251 (Bulgarian)
   - ISO-8859-1, windows-1252 (Western European languages)
   - ISO-8859-7, windows-1253 (Greek)
   - ISO-8859-8, windows-1255 (Visual and Logical Hebrew)
   - TIS-620 (Thai)

  .. note::
     Our ISO-8859-2 and windows-1250 (Hungarian) probers have been temporarily
     disabled until we can retrain the models.

  Requires Python 2.6, 2.7, or 3.3+.

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

  Install from `PyPI <https://pypi.python.org/pypi/chardet>`_::

      pip install chardet

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

  For users, docs are now available at https://chardet.readthedocs.io/.

  Command-line Tool
  -----------------

  chardet comes with a command-line script which reports on the encodings of one
  or more files::

      % chardetect somefile someotherfile
      somefile: windows-1252 with confidence 0.5
      someotherfile: ascii with confidence 1.0

  About
  -----

  This is a continuation of Mark Pilgrim's excellent chardet. Previously, two
  versions needed to be maintained: one that supported python 2.x and one that
  supported python 3.x.  We've recently merged with `Ian Cordasco <https://github.com/sigmavirus24>`_'s
  `charade <https://github.com/sigmavirus24/charade>`_ fork, so now we have one
  coherent version that works for Python 2.6+.

  :maintainer: Dan Blanchard


pkgId: 2ae3c43377b5c2d7ceb4891a061e936bc62cc3a75919965f9e766c8db3159401
name: rh-python36-cliff
arch: noarch
version: 2.14.1
epoch: 0
release: 1
summary: Command Line Interface Formulation Framework
url: https://docs.openstack.org/cliff/latest/
rpm_license: UNKNOWN
rpm_vendor: OpenStack <openstack-dev@lists.openstack.org>
rpm_group: Development/Libraries
rpm_buildhost: c6dd5e924de54dff9ac3a49cc81fd5eb
rpm_sourcerpm: rh-python36-cliff-2.14.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00887790-rh-python36-cliff/rh-python36-cliff-2.14.1-1.noarch.rpm
checksum_type: sha256
description:
  ========================
  Team and repository tags
  ========================

  .. image:: https://governance.openstack.org/tc/badges/cliff.svg
      :target: https://governance.openstack.org/tc/reference/tags/index.html

  .. Change things from this point on

  =======================================================
   cliff -- Command Line Interface Formulation Framework
  =======================================================

  cliff is a framework for building command line programs. It uses
  `setuptools entry points`_ to provide subcommands, output formatters, and
  other extensions.

  .. _setuptools entry points: http://setuptools.readthedocs.io/en/latest/pkg_resources.html#convenience-api

  * Free software: Apache license
  * Documentation: https://docs.openstack.org/cliff/latest/
  * Source: https://git.openstack.org/cgit/openstack/cliff
  * Bugs: https://bugs.launchpad.net/python-cliff


pkgId: 7f07a79576ea4c25cded38e91593b40c65ddd823914f736a14304907c30ee051
name: rh-python36-cmd2
arch: noarch
version: 0.9.12
epoch: 0
release: 1
summary: cmd2 - quickly build feature-rich and user-friendly interactive command line applications in Python
url: https://github.com/python-cmd2/cmd2
rpm_license: MIT
rpm_vendor: Catherine Devlin <catherine.devlin@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: 4ae0fc15b3414639a4df49feea48cf31
rpm_sourcerpm: rh-python36-cmd2-0.9.12-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00887878-rh-python36-cmd2/rh-python36-cmd2-0.9.12-1.noarch.rpm
checksum_type: sha256
description:
  cmd2: a tool for building interactive command line apps
  =======================================================
  [![Latest Version](https://img.shields.io/pypi/v/cmd2.svg?style=flat-square&label=latest%20stable%20version)](https://pypi.python.org/pypi/cmd2/)
  [![Build status](https://img.shields.io/travis/python-cmd2/cmd2.svg?style=flat-square&label=unix%20build)](https://travis-ci.org/python-cmd2/cmd2)
  [![Appveyor build status](https://img.shields.io/appveyor/ci/FedericoCeratto/cmd2.svg?style=flat-square&label=windows%20build)](https://ci.appveyor.com/project/FedericoCeratto/cmd2)
  [![Azure Build status](https://python-cmd2.visualstudio.com/cmd2/_apis/build/status/python-cmd2.cmd2?branch=master)](https://python-cmd2.visualstudio.com/cmd2/_build/latest?definitionId=1&branch=master)
  [![codecov](https://codecov.io/gh/python-cmd2/cmd2/branch/master/graph/badge.svg)](https://codecov.io/gh/python-cmd2/cmd2)
  [![Documentation Status](https://readthedocs.org/projects/cmd2/badge/?version=latest)](http://cmd2.readthedocs.io/en/latest/?badge=latest)

  cmd2 is a tool for building interactive command line applications in Python. Its goal is to make it
  quick and easy for developers to build feature-rich and user-friendly interactive command line
  applications.  It provides a simple API which is an extension of Python's built-in
  [cmd](https://docs.python.org/3/library/cmd.html) module.  cmd2 provides a wealth of features on top
  of cmd to make your life easier and eliminates much of the boilerplate code which would be necessary
  when using cmd.

  Click on image below to watch a short video demonstrating the capabilities of cmd2:
  [![Screenshot](cmd2.png)](https://youtu.be/DDU_JH6cFsA)

  Main Features
  -------------
  - Searchable command history (`history` command and `<Ctrl>+r`) - optionally persistent
  - Text file scripting of your application with `load` (`@`) and `_relative_load` (`@@`)
  - Python scripting of your application with ``pyscript``
  - Run shell commands with ``!``
  - Pipe command output to shell commands with `|`
  - Redirect command output to file with `>`, `>>`
  - Bare `>`, `>>` with no filename send output to paste buffer (clipboard)
  - `py` enters interactive Python console (opt-in `ipy` for IPython console)
  - Option to display long output using a pager with ``cmd2.Cmd.ppaged()``
  - Multi-line commands
  - Special-character command shortcuts (beyond cmd's `?` and `!`)
  - Command aliasing similar to bash `alias` command
  - Macros, which are similar to aliases, but they can contain argument placeholders
  - Ability to load commands at startup from an initialization script
  - Settable environment parameters
  - Parsing commands with arguments using `argparse`, including support for sub-commands
  - Unicode character support
  - Good tab-completion of commands, sub-commands, file system paths, and shell commands
  - Automatic tab-completion of `argparse` flags when using one of the `cmd2` `argparse` decorators
  - Support for Python 3.4+ on Windows, macOS, and Linux
  - Trivial to provide built-in help for all commands
  - Built-in regression testing framework for your applications (transcript-based testing)
  - Transcripts for use with built-in regression can be automatically generated from `history -t`
  - Alerts that seamlessly print while user enters text at prompt

  Python 2.7 support is EOL
  -------------------------
  The last version of cmd2 to support Python 2.7 is [0.8.9](https://pypi.org/project/cmd2/0.8.9/), released on August 21, 2018.

  Supporting Python 2 was an increasing burden on our limited resources.  Switching to support only Python 3 is allowing
  us to clean up the codebase, remove some cruft, and focus on developing new features.

  Installation
  ------------
  On all operating systems, the latest stable version of `cmd2` can be installed using pip:

  ```bash
  pip install -U cmd2
  ```

  cmd2 works with Python 3.4+ on Windows, macOS, and Linux. It is pure Python code with few 3rd-party dependencies.

  For information on other installation options, see
  [Installation Instructions](https://cmd2.readthedocs.io/en/latest/install.html) in the cmd2
  documentation.


  Documentation
  -------------
  The latest documentation for cmd2 can be read online here: https://cmd2.readthedocs.io/en/latest/

  It is available in HTML, PDF, and ePub formats.


  Feature Overview
  ----------------
  Instructions for implementing each feature follow.

  - Extension of the `cmd` module.  So capabilities provided by `cmd` still exist
      - Your applicaiton inherits from `cmd2.Cmd`, let's say you call this class `MyApp`
      ```Python
      import cmd2
      class MyApp(cmd2.Cmd):
        pass
      ```
      - Define a command named **foo** by creating a method named **do_foo**
      ```Python
      class MyApp(cmd2.Cmd):
          def do_foo(self, args):
              """This docstring is the built-in help for the foo command."""
              print('foo bar baz')
      ```
      - By default the docstring for your **do_foo** method is the help for the **foo** command
          - NOTE: This doesn't apply if you use one of the `argparse` decorators mentioned below
      - Can provide more custom help by creating a **help_foo** method (except when using `argparse` decorators)
      - Can provide custom tab-completion for the **foo** command by creating a **complete_foo** method
      - Easy to upgrade an existing `cmd` app to `cmd2`
      - Run your `cmd2` app using the built-in REPL by executing the **cmdloop** method

  - Searchable command history
      - Readline history using `<Ctrl>+r`, arrow keys, and other [Readline Shortcut keys](http://readline.kablamo.org/emacs.html)
          - Readline history can be persistent between application runs via optional argument to `cmd2.Cmd` initializer
      - `cmd2` `history` command provides flexible and powerful search
          - By design, this history does NOT persist between application runs
          - If you wish to exclude some of your custom commands from the history, append their names to the list at `Cmd.exclude_from_history`.
          - Do `help history` in any `cmd2` application for more information

  - Simple scripting using ASCII text files with one command + arguments per line
      - See the [Script files](https://cmd2.readthedocs.io/en/latest/freefeatures.html#script-files) section of the `cmd2` docs for more info
      - See [script.txt](https://github.com/python-cmd2/cmd2/blob/master/examples/scripts/script.txt) for a trivial example script that can be
      used in any `cmd2` application with the `load` command (or `@` shortcut)

  - Powerful and flexible built-in Python scripting of your application using the `pyscript` command
      - Run arbitrary Python scripts within your `cmd2` application with the ability to also call custom `cmd2` commands
      - No separate API for your end users to learn
          - Syntax for calling `cmd2` commands in a `pyscript` is essentially identical to what they would enter on the command line
      - See the [Python](https://cmd2.readthedocs.io/en/latest/freefeatures.html#python) section of the `cmd2` docs for more info
      - Also see the [python_scripting.py](https://github.com/python-cmd2/cmd2/blob/master/examples/python_scripting.py)
      example in conjunction with the [conditional.py](https://github.com/python-cmd2/cmd2/blob/master/examples/scripts/conditional.py) script

  - Parsing commands with `argparse`
      - Two decorators provide built-in capability for using `argparse.ArgumentParser` to parse command arguments
          - `cmd2.with_argparser` - all arguments are parsed by the `ArgumentParser`
          - `cmd2.with_argparser_and_unknown_args` - any arguments not parsed by the `ArgumentParser` get passed as a list

      ```Python
      import argparse
      from cmd2 import with_argparser

      argparser = argparse.ArgumentParser()
      argparser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
      argparser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
      argparser.add_argument('words', nargs='+', help='words to say')

      @with_argparser(argparser)
      def do_speak(self, args):
          """Repeats what you tell me to."""
          words = []
          for word in args.words:
              if args.piglatin:
                  word = '%s%say' % (word[1:], word[0])
              if args.shout:
                  word = word.upper()
              words.append(word)
          self.stdout.write('{}\n'.format(' '.join(words)))
      ```

      See https://cmd2.readthedocs.io/en/latest/argument_processing.html for more details

      NOTE: `cmd2` also provides the `ACArgumentParser` customization of `argparse.ArgumentParser` for prettier formatting
      of help and RangeAction type

  - `cmd2` applications function like a full-featured shell in many ways (and are cross-platform)
      - Run arbitrary shell commands by preceding them with `!` or `shell`
      - Redirect the output of any command to a file with `>` for overwrite or `>>` for append
          - If no file name provided after the `>`/`>>`, then output goes to the clipboard/pastebuffer
      - Pipe the output of any command to an arbitrary shell command with `|`
      - Create your own custom command aliases using the `alias` command
      - Create your own custom macros using the `macro` command (similar to aliases, but allow arguments)
      - Settable environment parameters that users can change during execution supported via `set` command
      - Option to display long output using a pager with ``cmd2.Cmd.ppaged()``
      - Optionally specify a startup script that end users can use to customize their environment

  - Top-notch tab-completion capabilities which are easy to use but very powerful
      - For a command **foo** implement a **complete_foo** method to provide custom tab completion for that command
          - But the helper methods within `cmd2` discussed below mean you would rarely have to implement this from scratch
      - Commands which use one of the `argparse` decorators have automatic tab-completion of `argparse` flags
          - And also provide help hints for values associated with these flags
          - Experiment with the [argprint.py](https://github.com/python-cmd2/cmd2/blob/master/examples/arg_print.py) example
          using the **oprint** and **pprint** commands to get a feel for how this works
      - `path_complete` helper method provides flexible tab-completion of file system paths
          - See the [paged_output.py](https://github.com/python-cmd2/cmd2/blob/master/examples/paged_output.py) example for a simple use case
          - See the [python_scripting.py](https://github.com/python-cmd2/cmd2/blob/master/examples/python_scripting.py) example for a more full-featured use case
      - `flag_based_complete` helper method for tab completion based on a particular flag preceding the token being completed
          - See the [tab_completion.py](https://github.com/python-cmd2/cmd2/blob/master/examples/tab_completion.py) example for a demonstration of how to use this feature
      - `index_based_complete` helper method for tab completion based on a fixed position in the input string
          - See the [tab_completion.py](https://github.com/python-cmd2/cmd2/blob/master/examples/tab_completion.py) example for a demonstration of how to use this feature
      - `basic_complete` helper method for tab completion against a list
      - `delimiter_complete` helper method for tab completion against a list but each match is split on a delimiter
          - See the [tab_autocompletion.py](https://github.com/python-cmd2/cmd2/blob/master/examples/tab_autocompletion.py) example for a demonstration of how to use this feature
      - `cmd2` in combination with `argparse` also provide several advanced capabilities for automatic tab-completion
              - See the [tab_autocompletion.py](https://github.com/python-cmd2/cmd2/blob/master/examples/tab_autocompletion.py) and
              [tab_autocomp_dynamic.py](https://github.com/python-cmd2/cmd2/blob/master/examples/tab_autocomp_dynamic.py) examples for more info

  - Multi-line commands

      Any command accepts multi-line input when its name is listed the `multiline_commands` optional argument to
      `cmd2.Cmd.__init`. The program will keep expecting input until a line ends with any of the characters listed in the
      `terminators` optional argument to `cmd2.Cmd.__init__()`  .  The default terminators are `;` and `/n` (empty newline).

  - Special-character shortcut commands (beyond cmd's "@" and "!")

      To create a single-character shortcut for a command, update `Cmd.shortcuts`.

  - Asynchronous alerts based on events happening in background threads
      - `cmd2` provides the following helper methods for providing information to users asynchronously even though the `cmd2`
      REPL is a line-oriented command interpreter:
          - `async_alert` - display an important message to the user while they are at the prompt in between commands
              - To the user it appears as if an alert message is printed above the prompt
          - `async_update_prompt` - update the prompt while the user is still typing at it
              - This is good for alerting the user to system changes dynamically in between commands
          - `set_window_title` - set the terminal window title
              - This changes the window title of the terminal that the user is running the `cmd2` app within


  Tutorials
  ---------

  A few tutorials on using cmd2 exist:

  * Florida PyCon 2017 talk: [slides](https://docs.google.com/presentation/d/1LRmpfBt3V-pYQfgQHdczf16F3hcXmhK83tl77R6IJtE), [video](https://www.youtube.com/watch?v=6m0RdpITaeY)
  * PyCon 2010 talk by Catherine Devlin, the original author: [video](http://pyvideo.org/pycon-us-2010/pycon-2010--easy-command-line-applications-with-c.html)
  * A nice brief step-by-step tutorial: [blog](https://kushaldas.in/posts/developing-command-line-interpreters-using-python-cmd2.html)


  Example Application
  -------------------

  Example cmd2 application (**examples/example.py**):

  ```python


  """
  A sample application for cmd2.
  """
  import argparse
  import random
  import cmd2

  class CmdLineApp(cmd2.Cmd):
      """ Example cmd2 application. """

      
      
      MUMBLES = ['like', '...', 'um', 'er', 'hmmm', 'ahh']
      MUMBLE_FIRST = ['so', 'like', 'well']
      MUMBLE_LAST = ['right?']

      def __init__(self):
          self.maxrepeats = 3
          shortcuts = dict(self.DEFAULT_SHORTCUTS)
          shortcuts.update({'&': 'speak'})

          
          super().__init__(use_ipython=False, multiline_commands=['orate'], shortcuts=shortcuts)

          
          self.settable['maxrepeats'] = 'max repetitions for speak command'

      speak_parser = argparse.ArgumentParser()
      speak_parser.add_argument('-p', '--piglatin', action='store_true', help='atinLay')
      speak_parser.add_argument('-s', '--shout', action='store_true', help='N00B EMULATION MODE')
      speak_parser.add_argument('-r', '--repeat', type=int, help='output [n] times')
      speak_parser.add_argument('words', nargs='+', help='words to say')

      @cmd2.with_argparser(speak_parser)
      def do_speak(self, args):
          """Repeats what you tell me to."""
          words = []
          for word in args.words:
              if args.piglatin:
                  word = '%s%say' % (word[1:], word[0])
              if args.shout:
                  word = word.upper()
              words.append(word)
          repetitions = args.repeat or 1
          for i in range(min(repetitions, self.maxrepeats)):
              
              self.poutput(' '.join(words))

      do_say = do_speak  # now "say" is a synonym for "speak"
      do_orate = do_speak  # another synonym, but this one takes multi-line input

      mumble_parser = argparse.ArgumentParser()
      mumble_parser.add_argument('-r', '--repeat', type=int, help='how many times to repeat')
      mumble_parser.add_argument('words', nargs='+', help='words to say')

      @cmd2.with_argparser(mumble_parser)
      def do_mumble(self, args):
          """Mumbles what you tell me to."""
          repetitions = args.repeat or 1
          for i in range(min(repetitions, self.maxrepeats)):
              output = []
              if (random.random() < .33):
                  output.append(random.choice(self.MUMBLE_FIRST))
              for word in args.words:
                  if (random.random() < .40):
                      output.append(random.choice(self.MUMBLES))
                  output.append(word)
              if (random.random() < .25):
                  output.append(random.choice(self.MUMBLE_LAST))
              self.poutput(' '.join(output))

  if __name__ == '__main__':
      c = CmdLineApp()
      c.cmdloop()
  ```

  The following is a sample session running example.py.
  Thanks to Cmd2's built-in transcript testing capability, it also serves as a test
  suite for example.py when saved as *transcript_regex.txt*.
  Running

  ```bash
  python example.py -t transcript_regex.txt
  ```
  will run all the commands in the transcript against `example.py`, verifying that the output produced
  matches the transcript.

  example/transcript_regex.txt:

  ```text




  (Cmd) set
  colors: /(True|False)/
  continuation_prompt: >/ /
  debug: False
  echo: False
  editor: /.*?/
  feedback_to_output: False
  locals_in_py: True
  maxrepeats: 3
  prompt: (Cmd)/ /
  quiet: False
  timing: False
  ```

  Note how a regular expression `/(True|False)/` is used for output of the **show color** command since
  colored text is currently not available for cmd2 on Windows.  Regular expressions can be used anywhere within a
  transcript file simply by enclosing them within forward slashes, `/`.


  Found a bug?
  ------------

  If you think you've found a bug, please first read through the open [Issues](https://github.com/python-cmd2/cmd2/issues). If you're confident it's a new bug, go ahead and create a new GitHub issue. Be sure to include as much information as possible so we can reproduce the bug.  At a minimum, please state the following:

  * ``cmd2`` version
  * Python version
  * OS name and version
  * What you did to cause the bug to occur
  * Include any traceback or error message associated with the bug


  Open source projects using cmd2
  -------------------------------

  Here are a few examples of open-source projects which use `cmd2`:

  * [cliff](https://github.com/openstack/cliff)
      * OpenStack Command Line Interface Formulation Framework
  * [tomcatmanager](https://github.com/tomcatmanager/tomcatmanager)
      * A command line tool and python library for managing a tomcat server
  * [clanvas](https://github.com/marklalor/clanvas)
      * Command-line client for Canvas by Instructure
  * [mptcpanalyzer](https://github.com/teto/mptcpanalyzer)
      * Tool to help analyze mptcp pcaps


pkgId: c0739061a136f38c711e2df6fc4a5daf806ffdc133b35b2e97f53eaf0ab9a86e
name: rh-python36-colorama
arch: noarch
version: 0.4.3
epoch: 0
release: 1
summary: Cross-platform colored terminal text.
url: https://github.com/tartley/colorama
rpm_license: BSD
rpm_vendor: Arnon Yaari <tartley@tartley.com>
rpm_group: Development/Libraries
rpm_buildhost: 9b402e8abfe34e4d92adbfe444fd6b31
rpm_sourcerpm: rh-python36-colorama-0.4.3-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143870-rh-python36-colorama/rh-python36-colorama-0.4.3-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/colorama.svg
      :target: https://pypi.python.org/pypi/colorama/
      :alt: Latest Version

  .. image:: https://travis-ci.org/tartley/colorama.svg?branch=master
      :target: https://travis-ci.org/tartley/colorama
      :alt: Build Status

  Download and docs:
      http://pypi.python.org/pypi/colorama
  Source code & Development:
      https://github.com/tartley/colorama

  Description
  ===========

  Makes ANSI escape character sequences (for producing colored terminal text and
  cursor positioning) work under MS Windows.

  ANSI escape character sequences have long been used to produce colored terminal
  text and cursor positioning on Unix and Macs. Colorama makes this work on
  Windows, too, by wrapping ``stdout``, stripping ANSI sequences it finds (which
  would appear as gobbledygook in the output), and converting them into the
  appropriate win32 calls to modify the state of the terminal. On other platforms,
  Colorama does nothing.

  Colorama also provides some shortcuts to help generate ANSI sequences
  but works fine in conjunction with any other ANSI sequence generation library,
  such as the venerable Termcolor (http://pypi.python.org/pypi/termcolor)
  or the fabulous Blessings (https://pypi.python.org/pypi/blessings).

  This has the upshot of providing a simple cross-platform API for printing
  colored terminal text from Python, and has the happy side-effect that existing
  applications or libraries which use ANSI sequences to produce colored output on
  Linux or Macs can now also work on Windows, simply by calling
  ``colorama.init()``.

  An alternative approach is to install ``ansi.sys`` on Windows machines, which
  provides the same behaviour for all applications running in terminals. Colorama
  is intended for situations where that isn't easy (e.g., maybe your app doesn't
  have an installer.)

  Demo scripts in the source code repository print some colored text using
  ANSI sequences. Compare their output under Gnome-terminal's built in ANSI
  handling, versus on Windows Command-Prompt using Colorama:

  .. image:: https://github.com/tartley/colorama/raw/master/screenshots/ubuntu-demo.png
      :width: 661
      :height: 357
      :alt: ANSI sequences on Ubuntu under gnome-terminal.

  .. image:: https://github.com/tartley/colorama/raw/master/screenshots/windows-demo.png
      :width: 668
      :height: 325
      :alt: Same ANSI sequences on Windows, using Colorama.

  These screengrabs show that, on Windows, Colorama does not support ANSI 'dim
  text'; it looks the same as 'normal text'.


  License
  =======

  Copyright Jonathan Hartley 2013. BSD 3-Clause license; see LICENSE file.


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

  None, other than Python. Tested on Python 2.5.5, 2.6.5, 2.7, 3.1.2, 3.2, 3.3,
  3.4 and 3.5.

  Usage
  =====

  Initialisation
  --------------

  Applications should initialise Colorama using:

  .. code-block:: python

      from colorama import init
      init()

  On Windows, calling ``init()`` will filter ANSI escape sequences out of any
  text sent to ``stdout`` or ``stderr``, and replace them with equivalent Win32
  calls.

  On other platforms, calling ``init()`` has no effect (unless you request other
  optional functionality; see "Init Keyword Args", below). By design, this permits
  applications to call ``init()`` unconditionally on all platforms, after which
  ANSI output should just work.

  To stop using colorama before your program exits, simply call ``deinit()``.
  This will restore ``stdout`` and ``stderr`` to their original values, so that
  Colorama is disabled. To resume using Colorama again, call ``reinit()``; it is
  cheaper to calling ``init()`` again (but does the same thing).


  Colored Output
  --------------

  Cross-platform printing of colored text can then be done using Colorama's
  constant shorthand for ANSI escape sequences:

  .. code-block:: python

      from colorama import Fore, Back, Style
      print(Fore.RED + 'some red text')
      print(Back.GREEN + 'and with a green background')
      print(Style.DIM + 'and in dim text')
      print(Style.RESET_ALL)
      print('back to normal now')

  ...or simply by manually printing ANSI sequences from your own code:

  .. code-block:: python

      print('\033[31m' + 'some red text')
      print('\033[30m') # and reset to default color

  ...or, Colorama can be used happily in conjunction with existing ANSI libraries
  such as Termcolor:

  .. code-block:: python

      from colorama import init
      from termcolor import colored

      
      init()

      
      print(colored('Hello, World!', 'green', 'on_red'))

  Available formatting constants are::

      Fore: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET.
      Back: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET.
      Style: DIM, NORMAL, BRIGHT, RESET_ALL

  ``Style.RESET_ALL`` resets foreground, background, and brightness. Colorama will
  perform this reset automatically on program exit.


  Cursor Positioning
  ------------------

  ANSI codes to reposition the cursor are supported. See ``demos/demo06.py`` for
  an example of how to generate them.


  Init Keyword Args
  -----------------

  ``init()`` accepts some ``**kwargs`` to override default behaviour.

  init(autoreset=False):
      If you find yourself repeatedly sending reset sequences to turn off color
      changes at the end of every print, then ``init(autoreset=True)`` will
      automate that:

      .. code-block:: python

          from colorama import init
          init(autoreset=True)
          print(Fore.RED + 'some red text')
          print('automatically back to default color again')

  init(strip=None):
      Pass ``True`` or ``False`` to override whether ansi codes should be
      stripped from the output. The default behaviour is to strip if on Windows
      or if output is redirected (not a tty).

  init(convert=None):
      Pass ``True`` or ``False`` to override whether to convert ANSI codes in the
      output into win32 calls. The default behaviour is to convert if on Windows
      and output is to a tty (terminal).

  init(wrap=True):
      On Windows, colorama works by replacing ``sys.stdout`` and ``sys.stderr``
      with proxy objects, which override the ``.write()`` method to do their work.
      If this wrapping causes you problems, then this can be disabled by passing
      ``init(wrap=False)``. The default behaviour is to wrap if ``autoreset`` or
      ``strip`` or ``convert`` are True.

      When wrapping is disabled, colored printing on non-Windows platforms will
      continue to work as normal. To do cross-platform colored output, you can
      use Colorama's ``AnsiToWin32`` proxy directly:

      .. code-block:: python

          import sys
          from colorama import init, AnsiToWin32
          init(wrap=False)
          stream = AnsiToWin32(sys.stderr).stream

          
          print >>stream, Fore.BLUE + 'blue text on stderr'

          
          print(Fore.BLUE + 'blue text on stderr', file=stream)


  Status & Known Problems
  =======================

  I've personally only tested it on Windows XP (CMD, Console2), Ubuntu
  (gnome-terminal, xterm), and OS X.

  Some presumably valid ANSI sequences aren't recognised (see details below),
  but to my knowledge nobody has yet complained about this. Puzzling.

  See outstanding issues and wishlist:
  https://github.com/tartley/colorama/issues

  If anything doesn't work for you, or doesn't do what you expected or hoped for,
  I'd love to hear about it on that issues list, would be delighted by patches,
  and would be happy to grant commit access to anyone who submits a working patch
  or two.


  Recognised ANSI Sequences
  =========================

  ANSI sequences generally take the form:

      ESC [ <param> ; <param> ... <command>

  Where ``<param>`` is an integer, and ``<command>`` is a single letter. Zero or
  more params are passed to a ``<command>``. If no params are passed, it is
  generally synonymous with passing a single zero. No spaces exist in the
  sequence; they have been inserted here simply to read more easily.

  The only ANSI sequences that colorama converts into win32 calls are::

      ESC [ 0 m       # reset all (colors and brightness)
      ESC [ 1 m       # bright
      ESC [ 2 m       # dim (looks same as normal brightness)
      ESC [ 22 m      # normal brightness

      
      ESC [ 30 m      # black
      ESC [ 31 m      # red
      ESC [ 32 m      # green
      ESC [ 33 m      # yellow
      ESC [ 34 m      # blue
      ESC [ 35 m      # magenta
      ESC [ 36 m      # cyan
      ESC [ 37 m      # white
      ESC [ 39 m      # reset

      
      ESC [ 40 m      # black
      ESC [ 41 m      # red
      ESC [ 42 m      # green
      ESC [ 43 m      # yellow
      ESC [ 44 m      # blue
      ESC [ 45 m      # magenta
      ESC [ 46 m      # cyan
      ESC [ 47 m      # white
      ESC [ 49 m      # reset

      
      ESC [ y;x H     # position cursor at x across, y down
      ESC [ y;x f     # position cursor at x across, y down
      ESC [ n A       # move cursor n lines up
      ESC [ n B       # move cursor n lines down
      ESC [ n C       # move cursor n characters forward
      ESC [ n D       # move cursor n characters backward

      
      ESC [ mode J    # clear the screen

      
      ESC [ mode K    # clear the line

  Multiple numeric params to the ``'m'`` command can be combined into a single
  sequence::

      ESC [ 36 ; 45 ; 1 m     # bright cyan text on magenta background

  All other ANSI sequences of the form ``ESC [ <param> ; <param> ... <command>``
  are silently stripped from the output on Windows.

  Any other form of ANSI sequence, such as single-character codes or alternative
  initial characters, are not recognised or stripped. It would be cool to add
  them though. Let me know if it would be useful for you, via the Issues on
  GitHub.


  Development
  ===========

  Help and fixes welcome!

  Running tests requires:

  - Michael Foord's ``mock`` module to be installed.
  - Tests are written using 2010-era updates to ``unittest``, and require
    Python 2.7 or greater, OR to have Michael Foord's ``unittest2`` module
    installed.

  To run tests::

     python -m unittest discover -p *_test.py

  This, like a few other handy commands, is captured in a ``Makefile``.

  If you use nose to run the tests, you must pass the ``-s`` flag; otherwise,
  ``nosetests`` applies its own proxy to ``stdout``, which confuses the unit
  tests.


  Thanks
  ======
  * Marc Schlaich (schlamar) for a ``setup.py`` fix for Python2.5.
  * Marc Abramowitz, reported & fixed a crash on exit with closed ``stdout``,
    providing a solution to issue #7's setuptools/distutils debate,
    and other fixes.
  * User 'eryksun', for guidance on correctly instantiating ``ctypes.windll``.
  * Matthew McCormick for politely pointing out a longstanding crash on non-Win.
  * Ben Hoyt, for a magnificent fix under 64-bit Windows.
  * Jesse at Empty Square for submitting a fix for examples in the README.
  * User 'jamessp', an observant documentation fix for cursor positioning.
  * User 'vaal1239', Dave Mckee & Lackner Kristof for a tiny but much-needed Win7
    fix.
  * Julien Stuyck, for wisely suggesting Python3 compatible updates to README.
  * Daniel Griffith for multiple fabulous patches.
  * Oscar Lesta for a valuable fix to stop ANSI chars being sent to non-tty
    output.
  * Roger Binns, for many suggestions, valuable feedback, & bug reports.
  * Tim Golden for thought and much appreciated feedback on the initial idea.
  * User 'Zearin' for updates to the README file.
  * John Szakmeister for adding support for light colors
  * Charles Merriam for adding documentation to demos
  * Jurko for a fix on 64-bit Windows CPython2.5 w/o ctypes
  * Florian Bruhin for a fix when stdout or stderr are None
  * Thomas Weininger for fixing ValueError on Windows
  * Remi Rampin for better Github integration and fixes to the README file
  * Simeon Visser for closing a file handle using 'with' and updating classifiers
    to include Python 3.3 and 3.4
  * Andy Neff for fixing RESET of LIGHT_EX colors.
  * Jonathan Hartley for the initial idea and implementation.


pkgId: 86e8b9d0078c36d36c95cebc3860c784f13cd888aecb3ac6be4e9702c8223855
name: rh-python36-configparser
arch: noarch
version: 3.5.0
epoch: 0
release: 1
summary: This library brings the updated configparser from Python 3.5 to Python 2.6-3.5.
url: http://docs.python.org/3/library/configparser.html
rpm_license: MIT
rpm_vendor: Łukasz Langa <lukasz@langa.pl>
rpm_group: Development/Libraries
rpm_buildhost: e73a63cab7f447a99b81c7792ae2fd75
rpm_sourcerpm: rh-python36-configparser-3.5.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00878997-rh-python36-configparser/rh-python36-configparser-3.5.0-1.noarch.rpm
checksum_type: sha256
description:
  ============
  configparser
  ============

  The ancient ``ConfigParser`` module available in the standard library 2.x has
  seen a major update in Python 3.2. This is a backport of those changes so that
  they can be used directly in Python 2.6 - 3.5.

  To use the ``configparser`` backport instead of the built-in version on both
  Python 2 and Python 3, simply import it explicitly as a backport::

    from backports import configparser

  If you'd like to use the backport on Python 2 and the built-in version on
  Python 3, use that invocation instead::

    import configparser

  For detailed documentation consult the vanilla version at
  http://docs.python.org/3/library/configparser.html.

  Why you'll love ``configparser``
  --------------------------------

  Whereas almost completely compatible with its older brother, ``configparser``
  sports a bunch of interesting new features:

  * full mapping protocol access (`more info
    <http://docs.python.org/3/library/configparser.html#mapping-protocol-access>`_)::

      >>> parser = ConfigParser()
      >>> parser.read_string("""
      [DEFAULT]
      location = upper left
      visible = yes
      editable = no
      color = blue

      [main]
      title = Main Menu
      color = green

      [options]
      title = Options
      """)
      >>> parser['main']['color']
      'green'
      >>> parser['main']['editable']
      'no'
      >>> section = parser['options']
      >>> section['title']
      'Options'
      >>> section['title'] = 'Options (editable: s)'
      >>> section['title']
      'Options (editable: no)'

  * there's now one default ``ConfigParser`` class, which basically is the old
    ``SafeConfigParser`` with a bunch of tweaks which make it more predictable for
    users. Don't need interpolation? Simply use
    ``ConfigParser(interpolation=None)``, no need to use a distinct
    ``RawConfigParser`` anymore.

  * the parser is highly `customizable upon instantiation
    <http://docs.python.org/3/library/configparser.html#customizing-parser-behaviour>`__
    supporting things like changing option delimiters, comment characters, the
    name of the DEFAULT section, the interpolation syntax, etc.

  * you can easily create your own interpolation syntax but there are two powerful
    implementations built-in (`more info
    <http://docs.python.org/3/library/configparser.html#interpolation-of-values>`__):

    * the classic ``s`` syntax (called ``BasicInterpolation``)

    * a new ``${buildout:like}`` syntax (called ``ExtendedInterpolation``)

  * fallback values may be specified in getters (`more info
    <http://docs.python.org/3/library/configparser.html#fallback-values>`__)::

      >>> config.get('closet', 'monster',
      ...            fallback='No such things as monsters')
      'No such things as monsters'

  * ``ConfigParser`` objects can now read data directly `from strings
    <http://docs.python.org/3/library/configparser.html#configparser.ConfigParser.read_string>`__
    and `from dictionaries
    <http://docs.python.org/3/library/configparser.html#configparser.ConfigParser.read_dict>`__.
    That means importing configuration from JSON or specifying default values for
    the whole configuration (multiple sections) is now a single line of code. Same
    goes for copying data from another ``ConfigParser`` instance, thanks to its
    mapping protocol support.

  * many smaller tweaks, updates and fixes

  A few words about Unicode
  -------------------------

  ``configparser`` comes from Python 3 and as such it works well with Unicode.
  The library is generally cleaned up in terms of internal data storage and
  reading/writing files.  There are a couple of incompatibilities with the old
  ``ConfigParser`` due to that. However, the work required to migrate is well
  worth it as it shows the issues that would likely come up during migration of
  your project to Python 3.

  The design assumes that Unicode strings are used whenever possible [1]_.  That
  gives you the certainty that what's stored in a configuration object is text.
  Once your configuration is read, the rest of your application doesn't have to
  deal with encoding issues. All you have is text [2]_. The only two phases when
  you should explicitly state encoding is when you either read from an external
  source (e.g. a file) or write back.

  Versioning
  ----------

  This backport is intended to keep 100% compatibility with the vanilla release in
  Python 3.2+. To help maintaining a version you want and expect, a versioning
  scheme is used where:

  * the first two numbers indicate the version of Python 3 from which the
    backport is done

  * a backport release number is provided as the final number (zero-indexed)

  For example, ``3.5.2`` is the **third** backport release of the
  ``configparser`` library as seen in Python 3.5.  Note that ``3.5.2`` does
  **NOT** necessarily mean this backport version is based on the standard library
  of Python 3.5.2.

  One exception from the 100% compatibility principle is that bugs fixed before
  releasing another minor Python 3 bugfix version **will be included** in the
  backport releases done in the mean time.

  Maintenance
  -----------

  This backport is maintained on BitBucket by Łukasz Langa, the current vanilla
  ``configparser`` maintainer for CPython:

  * `configparser Mercurial repository <https://bitbucket.org/ambv/configparser>`_

  * `configparser issue tracker <https://bitbucket.org/ambv/configparser/issues>`_

  Change Log
  ----------

  3.5.0
  ~~~~~

  * a complete rewrite of the backport; now single codebase working on Python
    2.6 - 3.5. To use on Python 3 import ``from backports import configparser``
    instead of the built-in version.

  * compatible with 3.5.1

  * fixes `BitBucket issue #1
    <https://bitbucket.org/ambv/configparser/issue/1>`_: versioning non-compliant
    with PEP 386

  * fixes `BitBucket issue #3
    <https://bitbucket.org/ambv/configparser/issue/3>`_: ``reload(sys);
    sys.setdefaultencoding('utf8')`` in setup.py

  * fixes `BitBucket issue #5
    <https://bitbucket.org/ambv/configparser/issue/5>`_: Installing the backport
    on Python 3 breaks virtualenv

  * fixes `BitBucket issue #6
    <https://bitbucket.org/ambv/configparser/issue/6>`_: PyPy compatibility

  3.5.0b2
  ~~~~~~~

  * second beta of 3.5.0, not using any third-party futurization libraries

  3.5.0b1
  ~~~~~~~

  * first beta of 3.5.0, using python-future

  * for the full feature list, see `3.5.0`_

  3.3.0r2
  ~~~~~~~

  * updated the fix for `#16820 <http://bugs.python.org/issue16820>`_: parsers
    now preserve section order when using ``__setitem__`` and ``update``

  3.3.0r1
  ~~~~~~~

  * compatible with 3.3.0 + fixes for `#15803
    <http://bugs.python.org/issue15803>`_ and `#16820
    <http://bugs.python.org/issue16820>`_

  * fixes `BitBucket issue #4
    <https://bitbucket.org/ambv/configparser/issue/4>`_: ``read()`` properly
    treats a bytestring argument as a filename

  * `ordereddict <http://pypi.python.org/pypi/ordereddict>`_ dependency required
    only for Python 2.6

  * `unittest2 <http://pypi.python.org/pypi/unittest2>`_ explicit dependency
    dropped. If you want to test the release, add ``unittest2`` on your own.

  3.2.0r3
  ~~~~~~~

  * proper Python 2.6 support

    * explicitly stated the dependency on `ordereddict
      <http://pypi.python.org/pypi/ordereddict>`_

    * numbered all formatting braces in strings

  * explicitly says that Python 2.5 support won't happen (too much work necessary
    without abstract base classes, string formatters, the ``io`` library, etc.)

  * some healthy advertising in the README

  3.2.0r2
  ~~~~~~~

  * a backport-specific change: for convenience and basic compatibility with the
    old ConfigParser, bytestrings are now accepted as section names, options and
    values.  Those strings are still converted to Unicode for internal storage so
    in any case when such conversion is not possible (using the 'ascii' codec),
    UnicodeDecodeError is raised.

  3.2.0r1
  ~~~~~~~

  * the first public release compatible with 3.2.0 + fixes for `#11324
    <http://bugs.python.org/issue11324>`_, `#11670
    <http://bugs.python.org/issue11670>`_ and `#11858
    <http://bugs.python.org/issue11858>`_.

  Conversion Process
  ------------------

  This section is technical and should bother you only if you are wondering how
  this backport is produced. If the implementation details of this backport are
  not important for you, feel free to ignore the following content.

  ``configparser`` is converted using `python-future
  <http://python-future.org>`_ and free time.  Because a fully automatic
  conversion was not doable, I took the following branching approach:

  * the ``3.x`` branch holds unchanged files synchronized from the upstream
    CPython repository. The synchronization is currently done by manually copying
    the required files and stating from which CPython changeset they come from.

  * the ``default`` branch holds a version of the ``3.x`` code with some tweaks
    that make it independent from libraries and constructions unavailable on 2.x.
    Code on this branch still *must* work on the corresponding Python 3.x but
    will also work on Python 2.6 and 2.7 (including PyPy).  You can check this
    running the supplied unit tests with ``tox``.

  The process works like this:

  1. I update the ``3.x`` branch with new versions of files.  Note that the
     actual ``configparser.py`` file is now just a proxy for sources held in
     ``backports/configparser/__init__.py``.

  2. I check for new names in ``__all__`` and update imports in
     ``configparser.py`` accordingly. I run the tests on Python 3. Commit.

  3. I merge the new commit to ``default``. I run ``tox``. Commit.

  4. If there are necessary changes, I do them now (on ``default``). Note that
     the changes should be written in the syntax subset supported by Python
     2.6.

  5. I run ``tox``. If it works, I update the docs and release the new version.
     Otherwise, I go back to point 3. I might use ``pasteurize`` to suggest me
     required changes but usually I do them manually to keep resulting code in
     a nicer form.


  Footnotes
  ---------

  .. [1] To somewhat ease migration, passing bytestrings is still supported but
         they are converted to Unicode for internal storage anyway. This means
         that for the vast majority of strings used in configuration files, it
         won't matter if you pass them as bytestrings or Unicode. However, if you
         pass a bytestring that cannot be converted to Unicode using the naive
         ASCII codec, a ``UnicodeDecodeError`` will be raised. This is purposeful
         and helps you manage proper encoding for all content you store in
         memory, read from various sources and write back.

  .. [2] Life gets much easier when you understand that you basically manage
         **text** in your application.  You don't care about bytes but about
         letters.  In that regard the concept of content encoding is meaningless.
         The only time when you deal with raw bytes is when you write the data to
         a file.  Then you have to specify how your text should be encoded.  On
         the other end, to get meaningful text from a file, the application
         reading it has to know which encoding was used during its creation.  But
         once the bytes are read and properly decoded, all you have is text.  This
         is especially powerful when you start interacting with multiple data
         sources.  Even if each of them uses a different encoding, inside your
         application data is held in abstract text form.  You can program your
         business logic without worrying about which data came from which source.
         You can freely exchange the data you store between sources.  Only
         reading/writing files requires encoding your text to bytes.


pkgId: 10367e87efc8cd5b6d824ebdc46e65ff96806e6c98d1ca2725cb88616d6723e9
name: rh-python36-constantly
arch: noarch
version: 15.1.0
epoch: 0
release: 1
summary: Symbolic constants in Python
url: https://github.com/twisted/constantly
rpm_license: MIT
rpm_vendor: Twisted Matrix Labs Developers <UNKNOWN>
rpm_group: Development/Libraries
rpm_buildhost: b771b330356440d7b8206c6c9735f4f8
rpm_sourcerpm: rh-python36-constantly-15.1.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00878998-rh-python36-constantly/rh-python36-constantly-15.1.0-1.noarch.rpm
checksum_type: sha256
description:
  Constantly
  ==========

  A library that provides symbolic constant support.
  It includes collections and constants with text, numeric, and bit flag values.
  Originally ``twisted.python.constants`` from the `Twisted <https://twistedmatrix.com/>`_ project.


  Tests
  -----

  To run tests::

      $ tox

  This will run tests on Python 2.7, 3.3, 3.4, and PyPy, as well as doing coverage and pyflakes checks.


pkgId: 083c2be0951b9ea58192d26aeac5b358531ad77041e8722fcb8195cdcad33923
name: rh-python36-cryptography
arch: ppc64le
version: 2.8
epoch: 0
release: 1
summary: cryptography is a package which provides cryptographic recipes and primitives to Python developers.
url: https://github.com/pyca/cryptography
rpm_license: BSD or Apache License, Version 2.0
rpm_vendor: The cryptography developers <cryptography-dev@python.org>
rpm_group: Development/Libraries
rpm_buildhost: d13c2eec27c94bb094235093c6abd895
rpm_sourcerpm: rh-python36-cryptography-2.8-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01064724-rh-python36-cryptography/rh-python36-cryptography-2.8-1.ppc64le.rpm
checksum_type: sha256
description:
  pyca/cryptography
  =================

  .. image:: https://img.shields.io/pypi/v/cryptography.svg
      :target: https://pypi.python.org/pypi/cryptography/
      :alt: Latest Version

  .. image:: https://readthedocs.org/projects/cryptography/badge/?version=latest
      :target: https://cryptography.io
      :alt: Latest Docs

  .. image:: https://travis-ci.org/pyca/cryptography.svg?branch=master
      :target: https://travis-ci.org/pyca/cryptography

  .. image:: https://codecov.io/github/pyca/cryptography/coverage.svg?branch=master
      :target: https://codecov.io/github/pyca/cryptography?branch=master


  ``cryptography`` is a package which provides cryptographic recipes and
  primitives to Python developers.  Our goal is for it to be your "cryptographic
  standard library". It supports Python 2.6-2.7, Python 3.4+, and PyPy 5.3+.

  ``cryptography`` includes both high level recipes and low level interfaces to
  common cryptographic algorithms such as symmetric ciphers, message digests, and
  key derivation functions. For example, to encrypt something with
  ``cryptography``'s high level symmetric encryption recipe:

  .. code-block:: pycon

      >>> from cryptography.fernet import Fernet
      >>> # Put this somewhere safe!
      >>> key = Fernet.generate_key()
      >>> f = Fernet(key)
      >>> token = f.encrypt(b"A really secret message. Not for prying eyes.")
      >>> token
      '...'
      >>> f.decrypt(token)
      'A really secret message. Not for prying eyes.'

  You can find more information in the `documentation`_.

  You can install ``cryptography`` with:

  .. code-block:: console

      $ pip install cryptography

  For full details see `the installation documentation`_.

  Discussion
  ~~~~~~~~~~

  If you run into bugs, you can file them in our `issue tracker`_.

  We maintain a `cryptography-dev`_ mailing list for development discussion.

  You can also join ``#cryptography-dev`` on Freenode to ask questions or get
  involved.


  .. _`documentation`: https://cryptography.io/
  .. _`the installation documentation`: https://cryptography.io/en/latest/installation/
  .. _`issue tracker`: https://github.com/pyca/cryptography/issues
  .. _`cryptography-dev`: https://mail.python.org/mailman/listinfo/cryptography-dev


pkgId: b9c00736de42f79099882a384782f16712feb07f78995cb25db741c4ac1008f8
name: rh-python36-cryptography-debuginfo
arch: ppc64le
version: 2.8
epoch: 0
release: 1
summary: Debug information for package rh-python36-cryptography
url: https://github.com/pyca/cryptography
rpm_license: BSD or Apache License, Version 2.0
rpm_vendor: The cryptography developers <cryptography-dev@python.org>
rpm_group: Development/Debug
rpm_buildhost: d13c2eec27c94bb094235093c6abd895
rpm_sourcerpm: rh-python36-cryptography-2.8-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01064724-rh-python36-cryptography/rh-python36-cryptography-debuginfo-2.8-1.ppc64le.rpm
checksum_type: sha256
description:
  This package provides debug information for package rh-python36-cryptography.
  Debug information is useful when developing applications that use this
  package or when debugging this package.


pkgId: f96d04bfdbbcef0441dce0b13138f587fdffcd241da729921156d1fdc4e1f169
name: rh-python36-daphne
arch: noarch
version: 1.3.0
epoch: 0
release: 1
summary: Django ASGI (HTTP/WebSocket) server
url: https://github.com/django/daphne
rpm_license: BSD
rpm_vendor: Django Software Foundation <foundation@djangoproject.com>
rpm_group: Development/Libraries
rpm_buildhost: b7cceba238114bfd85322e64b89e4fb6
rpm_sourcerpm: rh-python36-daphne-1.3.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879000-rh-python36-daphne/rh-python36-daphne-1.3.0-1.noarch.rpm
checksum_type: sha256
description:
  daphne
  ======

  .. image:: https://api.travis-ci.org/django/daphne.svg
      :target: https://travis-ci.org/django/daphne

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

  Daphne is a HTTP, HTTP2 and WebSocket protocol server for
  `ASGI <https://channels.readthedocs.io/en/latest/asgi.html>`_, and developed
  to power Django Channels.

  It supports automatic negotiation of protocols; there's no need for URL
  prefixing to determine WebSocket endpoints versus HTTP endpoints.


  Running
  -------

  Simply point Daphne to your ASGI channel layer instance, and optionally
  set a bind address and port (defaults to localhost, port 8000)::

      daphne -b 0.0.0.0 -p 8001 django_project.asgi:channel_layer

  If you intend to run daphne behind a proxy server you can use UNIX
  sockets to communicate between the two::

      daphne -u /tmp/daphne.sock django_project.asgi:channel_layer

  If daphne is being run inside a process manager such as
  `Circus <https://github.com/circus-tent/circus/>`_ you might
  want it to bind to a file descriptor passed down from a parent process.
  To achieve this you can use the --fd flag::

      daphne --fd 5 django_project.asgi:channel_layer

  If you want more control over the port/socket bindings you can fall back to
  using `twisted's endpoint description strings
  <http://twistedmatrix.com/documents/current/api/twisted.internet.endpoints.html#serverFromString>`_
  by using the `--endpoint (-e)` flag, which can be used multiple times.
  This line would start a SSL server on port 443, assuming that `key.pem` and `crt.pem`
  exist in the current directory (requires pyopenssl to be installed)::

      daphne -e ssl:443:privateKey=key.pem:certKey=crt.pem django_project.asgi:channel_layer

  Endpoints even let you use the ``txacme`` endpoint syntax to get automatic certificates
  from Let's Encrypt, which you can read more about at http://txacme.readthedocs.io/en/stable/.

  To see all available command line options run daphne with the *-h* flag.


  HTTP/2 Support
  --------------

  Daphne 1.1 and above supports terminating HTTP/2 connections natively. You'll
  need to do a couple of things to get it working, though. First, you need to
  make sure you install the Twisted ``http2`` and ``tls`` extras::

      pip install -U Twisted[tls,http2]

  Next, because all current browsers only support HTTP/2 when using TLS, you will
  need to start Daphne with TLS turned on, which can be done using the Twisted endpoint syntax::

      daphne -e ssl:443:privateKey=key.pem:certKey=crt.pem django_project.asgi:channel_layer

  Alternatively, you can use the ``txacme`` endpoint syntax or anything else that
  enables TLS under the hood.

  You will also need to be on a system that has **OpenSSL 1.0.2 or greater**; if you are
  using Ubuntu, this means you need at least 16.04.

  Now, when you start up Daphne, it should tell you this in the log::

      2017-03-18 19:14:02,741 INFO     Starting server at ssl:port=8000:privateKey=privkey.pem:certKey=cert.pem, channel layer django_project.asgi:channel_layer.
      2017-03-18 19:14:02,742 INFO     HTTP/2 support enabled

  Then, connect with a browser that supports HTTP/2, and everything should be
  working. It's often hard to tell that HTTP/2 is working, as the log Daphne gives you
  will be identical (it's HTTP, after all), and most browsers don't make it obvious
  in their network inspector windows. There are browser extensions that will let
  you know clearly if it's working or not.

  Daphne only supports "normal" requests over HTTP/2 at this time; there is not
  yet support for extended features like Server Push. It will, however, result in
  much faster connections and lower overheads.

  If you have a reverse proxy in front of your site to serve static files or
  similar, HTTP/2 will only work if that proxy understands and passes through the
  connection correctly.


  Root Path (SCRIPT_NAME)
  -----------------------

  In order to set the root path for Daphne, which is the equivalent of the
  WSGI ``SCRIPT_NAME`` setting, you have two options:

  * Pass a header value ``Daphne-Root-Path``, with the desired root path as a
    URLencoded ASCII value. This header will not be passed down to applications.

  * Set the ``--root-path`` commandline option with the desired root path as a
    URLencoded ASCII value.

  The header takes precedence if both are set. As with ``SCRIPT_ALIAS``, the value
  should start with a slash, but not end with one; for example::

      daphne --root-path=/forum django_project.asgi:channel_layer

  Dependencies
  ------------

  All Channels projects currently support Python 2.7, 3.4 and 3.5. `daphne` requires Twisted 17.1 or
  greater.


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

  Please refer to the
  `main Channels contributing docs <https://github.com/django/channels/blob/master/CONTRIBUTING.rst>`_.
  That also contains advice on how to set up the development environment and run the tests.


  Maintenance and Security
  ------------------------

  To report security issues, please contact security@djangoproject.com. For GPG
  signatures and more security process information, see
  https://docs.djangoproject.com/en/dev/internals/security/.

  To report bugs or request new features, please open a new GitHub issue.

  This repository is part of the Channels project. For the shepherd and maintenance team, please see the
  `main Channels readme <https://github.com/django/channels/blob/master/README.rst>`_.


pkgId: ea11ba10be826b368f210d0eb98c4c776975797e484dcb926e9d94c9b98683b7
name: rh-python36-debtcollector
arch: noarch
version: 1.21.0
epoch: 0
release: 1
url: https://docs.openstack.org/debtcollector/latest
rpm_license: UNKNOWN
rpm_vendor: OpenStack <openstack-discuss@lists.openstack.org>
rpm_group: Development/Libraries
rpm_buildhost: b49d51224cfb4f45855b148360abcb62
rpm_sourcerpm: rh-python36-debtcollector-1.21.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00887944-rh-python36-debtcollector/rh-python36-debtcollector-1.21.0-1.noarch.rpm
checksum_type: sha256
summary:
  A collection of Python deprecation patterns and strategies that help you collect your technical debt in a non-destructive manner.

description:
  ========================
  Team and repository tags
  ========================

  .. image:: https://governance.openstack.org/tc/badges/debtcollector.svg
      :target: https://governance.openstack.org/tc/reference/tags/index.html

  .. Change things from this point on

  Debtcollector
  =============

  .. image:: https://img.shields.io/pypi/v/debtcollector.svg
      :target: https://pypi.org/project/debtcollector/
      :alt: Latest Version

  A collection of Python deprecation patterns and strategies that help you
  collect your technical debt in a non-destructive manner. The goal of this
  library is to provide well documented developer facing deprecation
  patterns that start of with a basic set and can expand into a larger
  set of patterns as time goes on. The desired output of these patterns
  is to apply the warnings module to emit DeprecationWarning or PendingDeprecationWarning
  or similar derivative to developers using libraries (or potentially
  applications) about future deprecations.


  * Free software: Apache license
  * Documentation: https://docs.openstack.org/debtcollector/latest
  * Source: https://git.openstack.org/cgit/openstack/debtcollector
  * Bugs: https://bugs.launchpad.net/debtcollector
  * Release Notes: https://docs.openstack.org/releasenotes/debtcollector


pkgId: f5e625eba83c9e7ee83e69a2b7da61e1b94f3828afeca2564db49fceb4b560ab
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: 840790d3bcf64398ba782ec2ca61a093
rpm_sourcerpm: rh-python36-decorator-4.4.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143871-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: 2fc41423c2ce30734179aa36d0032b45240467d2259109c8297ae365e96e57d0
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: 79c4426d489b4471a0923849e57d6d5b
rpm_sourcerpm: rh-python36-defusedxml-0.5.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879002-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: b53e88ce86102123fa1a9a07435872ea801178da1a527a6bb9b7f3887ed531db
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: c7929a9f359a448c985c649d4086c75e
rpm_sourcerpm: rh-python36-deprecation-2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879003-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: ab0d3cae7af96851d2c5273ddb6c4f20e855248cda75f6cf1aed437485e41fa8
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: 48062724062f4967b6027431e38470fb
rpm_sourcerpm: rh-python36-django-auth-ldap-2.1.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143445-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: 56438a52b81f910bb79459b00b2eb2a46d997cdcfdf75c77151e4b9f260c05b9
name: rh-python36-django-cors-headers
arch: noarch
version: 3.2.0
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: 66c180196d774a1b8e51297a28933051
rpm_sourcerpm: rh-python36-django-cors-headers-3.2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143446-rh-python36-django-cors-headers/rh-python36-django-cors-headers-3.2.0-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: e17b3054a177fd14cd0a0f88ff4d6536fbad9e28959ed4fef523da38a5941401
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: de4f2dcfb7c84818b43f87c7946f7301
rpm_sourcerpm: rh-python36-django-crum-0.7.5-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143447-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: db8c3e8d821eb64c1f951f08a57c5feb4cef9f78809151c438018134938f5e1a
name: rh-python36-django-extensions
arch: noarch
version: 2.2.5
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: 2261ee8d035e44cabb46dcce8ab0e822
rpm_sourcerpm: rh-python36-django-extensions-2.2.5-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143448-rh-python36-django-extensions/rh-python36-django-extensions-2.2.5-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: ed56ab2cd7fcda62d1601b203ddd4133f263c9d2c88001ad06684ace4ba15330
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: d50d041b16de484580aedfa3be96ca90
rpm_sourcerpm: rh-python36-django-jsonfield-1.2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00972355-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: d8d73265872d122dc618485ffbf0be98735bcb994635bf82f1cc0c21bc239717
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: 4b8d8b487f344de7826df8d2e3070fbf
rpm_sourcerpm: rh-python36-django-polymorphic-2.1.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143450-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: 1bcb10fb72cf8060667074bbd15f382ce55428a7abd0e259496b4c6bf1226b3f
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: b3f8375127834c4296af3620b33ed51a
rpm_sourcerpm: rh-python36-django-qsstats-magic-1.1.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01117703-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: 41a2d1d98788fd56bc0da003bfb5eba1cf70c163335fde916b7667795146fc4f
name: rh-python36-django-solo
arch: noarch
version: 1.1.3
epoch: 0
release: 1
url: http://github.com/lazybird/django-solo/
rpm_license: Creative Commons Attribution 3.0 Unported
rpm_vendor: lazybird <UNKNOWN>
rpm_group: Development/Libraries
rpm_buildhost: 14771d0c5bea47b6aa746e85feba7951
rpm_sourcerpm: rh-python36-django-solo-1.1.3-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879017-rh-python36-django-solo/rh-python36-django-solo-1.1.3-1.noarch.rpm
checksum_type: sha256
summary:
  django-solo helps working with singletons: things like global settings that you want to edit from the admin site.

description:
  Django Solo
  ===========


      +---------------------------+
      |                           |
      |                           |
      |             \             | Django Solo helps working with singletons:
      |             /\            | database tables that only have one row.
      |           >=)'>           | Singletons are useful for things like global
      |             \/            | settings that you want to edit from the admin
      |             /             | instead of having them in Django settings.py.
      |                           |
      |                           |
      +---------------------------+


  Features
  --------

  Solo helps you enforce instantiating only one instance of a model in django.

  * You define the model that will hold your singleton object.
  * django-solo gives helper parent class for your model and the admin classes.
  * You get an admin interface that's aware you only have one object.
  * You can retrieve the object from templates.
  * By enabling caching, the database is not queried intensively.

  Use Cases
  --------

  Django Solo is also great for use with singleton objects that have a one to many relationship. Like the use case below where you have a 'Home Slider" that has many "Slides".

  * Global or default settings
  * An image slider that has many slides
  * A page section that has sub-sections
  * A team bio with many team members

  There are many cases where it makes sense for the parent in a one to many relationship to be limited to a single instance.

  Usage Example

  ```python


  from django.db import models
  from solo.models import SingletonModel

  class SiteConfiguration(SingletonModel):
      site_name = models.CharField(max_length=255, default='Site Name')
      maintenance_mode = models.BooleanField(default=False)

      def __unicode__(self):
          return u"Site Configuration"

      class Meta:
          verbose_name = "Site Configuration"
  ```

  ```python


  from django.contrib import admin
  from solo.admin import SingletonModelAdmin
  from config.models import SiteConfiguration

  admin.site.register(SiteConfiguration, SingletonModelAdmin)


  from .models import SiteConfiguration
  config = SiteConfiguration.objects.get()


  config = SiteConfiguration.get_solo()
  ```


  In your model, note how you did not have to provide a `verbose_name_plural` field -
  That's because Django Solo uses the `verbose_name` instead.

  If you're changing an existing model (which already has some objects stored in the database) to a singleton model, you can explicitly provide the id of the row in the database for django-solo to use. This can be done by setting `singleton_instance_id` property on the model:

  ```python
  class SiteConfiguration(SingletonModel):
      singleton_instance_id = 24
      
  ```

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

  This application requires Django >= 1.6.

  * Install the package using `pip install django-solo`
  * Add ``solo`` or ``solo.apps.SoloAppConfig`` to your ``INSTALLED_APPS`` setting.

  This is how you run tests:

      ./manage.py test solo --settings=solo.tests.settings


  Admin
  -----

  The standard Django admin does not fit well when working with singleton,
  for instance, if you need some global site settings to be edited in the admin.
  Django Solo provides a modified admin for that.


  ![django-solo admin](https://raw.github.com/lazybird/django-solo/master/docs/images/django-solo-admin.jpg "django-solo admin")


  * In the admin home page where all applications are listed, we have a `config`
    application that holds a singleton model for site configuration.
  * The configuration object can only be changed, there's no link for "add" (1).
  * The link to the configuration page (2) directly goes to the form page - no
    need for an intermediary object list page, since there's only one object.
  * The edit page has a modified breadcrumb (3) to avoid linking to the
    intermediary object list page.
  * From the edit page, we cannot delete the object (4) nor can we add a new one (5).


  Availability from templates
  ---------------------------

  The singleton object can be retrieved from template by giving the Django model
  dotted path:

  ```django
  {% get_solo 'app_label.ModelName' as my_config %}
  ```


  Example:

  ```django
  {% load solo_tags %}
  {% get_solo 'config.SiteConfiguration' as site_config %}
  {{ site_config.site_name }}
  {{ site_config.maintenance_mode }}
  ```


  If you're extending a template, be sure to use the tag in the proper scope.

  Right:

  ```django
  {% extends "index.html" %}
  {% load solo_tags %}

  {% block content %}
      {% get_solo 'config.SiteConfiguration' as site_config %}
      {{ site_config.site_name }}
  {% endblock content %}
  ```

  Wrong:

  ```django
  {% extends "index.html" %}
  {% load solo_tags %}
  {% get_solo 'config.SiteConfiguration' as site_config %}

  {% block content %}
      {{ site_config.site_name }}
  {% endblock content %}
  ```


  Caching
  -------

  By default caching is disabled: every time `get_solo` retrieves the singleton
  object, there will be a database query.

  You can enable caching to only query the database when initially retrieving the
  object. The cache will also be updated when updates are made from the admin.

  The cache timeout is controlled via the `SOLO_CACHE_TIMEOUT` settings.
  The cache backend to be used is controlled via the `SOLO_CACHE` settings.


  Settings
  --------



  You can retrieve your singleton object in templates using the `get_solo`
  template tag.

  You can change the name `get_solo` using the
  `GET_SOLO_TEMPLATE_TAG_NAME` setting.

  ```python
  GET_SOLO_TEMPLATE_TAG_NAME = 'get_config'
  ```



  Django provides a way to define multiple cache backends with the `CACHES`
  settings. If you want the singleton object to be cached separately, you
  could define the `CACHES` and the `SOLO_CACHE` settings like this:

  ```python
  CACHES = {
      'default': {
          'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
          'LOCATION': '127.0.0.1:11211',
      },
      'local': {
          'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
      },
  }

  SOLO_CACHE = 'local'
  ```


  Caching will be disabled if set to `None`.




  The cache timeout in seconds.

  ```python
  SOLO_CACHE_TIMEOUT = 60*5  # 5 mins
  ```



  The prefix to use for the cache key.

  ```python
  SOLO_CACHE_PREFIX = 'solo'
  ```


  Getting the code
  ===============

  The code is hosted at https://github.com/lazybird/django-solo/

  Check out the latest development version anonymously with::

      $ git clone git://github.com/lazybird/django-solo.git


pkgId: 828745d46500c05b2af2a76cf253082b510e603529903dde914e5c24428978e0
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: f5ae2f238aca43e99d55f538693aba78
rpm_sourcerpm: rh-python36-django-split-settings-1.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143523-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: c59db816281b19078d7cda4bc2e39097873233913d01c6090792778713553349
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: bb46eb2be79346fea9210cbc5846897a
rpm_sourcerpm: rh-python36-django-taggit-1.2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143524-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: 2fca3b85f1b113b30828d8236ffc9d02877c404b5fefbfb35b6c35f5048c02a3
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: 324797bddd1d4762a03e135c3ad95acd
rpm_sourcerpm: rh-python36-djangorestframework-3.11.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143526-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: 461a7e2a11e445a5962f65abb8dd422a28682dea21040bcef3fae20315cfe720
name: rh-python36-djangorestframework-yaml
arch: noarch
version: 1.0.3
epoch: 0
release: 1
summary: YAML support for Django REST Framework
description: UNKNOWN
url: https://github.com/jpadilla/django-rest-framework-yaml
rpm_license: BSD
rpm_vendor: José Padilla <hello@jpadilla.com>
rpm_group: Development/Libraries
rpm_buildhost: 8d9b98cf962a4855936285f4286ae61c
rpm_sourcerpm: rh-python36-djangorestframework-yaml-1.0.3-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
checksum_type: sha256
location_href:
  00879015-rh-python36-djangorestframework-yaml/rh-python36-djangorestframework-yaml-1.0.3-1.noarch.rpm


pkgId: d765ed6b16d740a171e76ee94fe13eeed61c6299b98e6a0d4117a60d7a712dd5
name: rh-python36-docutils
arch: noarch
version: 0.15.2
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: f4a762c2ebac42daa75795ced4e160cc
rpm_sourcerpm: rh-python36-docutils-0.15.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01031453-rh-python36-docutils/rh-python36-docutils-0.15.2-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: c79c5accbfec15bf99716bb6b6b62de0b32bdab520359eae190a3d44f4c2ac36
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: 840069395e294fa385d02fd6fc8bad17
rpm_sourcerpm: rh-python36-dogpile.cache-0.9.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143872-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: ed9f01dca6bfc8557dd170972793be872c614cab7709a0119007814e27e8ed05
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: a0ccde6b41cd4529b7dd92effbe3d57b
rpm_sourcerpm: rh-python36-extras-1.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00887915-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: ec03d55ad3d05952a01fb83b80eb4458c4e3e379be565352a17fe0cfe6c94a9b
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: 5e372eab29c54d93911994d6dc3b41c7
rpm_sourcerpm: rh-python36-fixtures-3.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00887953-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: 80598fd3a652cb62653658d23f1bb08610d0067872e0e846a1c756d687fac8f9
name: rh-python36-future
arch: noarch
version: 0.17.1
epoch: 0
release: 1
summary: Clean single-source support for Python 3 and 2
url: https://python-future.org
rpm_license: MIT
rpm_vendor: Ed Schofield <ed@pythoncharmers.com>
rpm_group: Development/Libraries
rpm_buildhost: d2e34ca469f646889399a8d866f2f64d
rpm_sourcerpm: rh-python36-future-0.17.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879023-rh-python36-future/rh-python36-future-0.17.1-1.noarch.rpm
checksum_type: sha256
description:
  future: Easy, safe support for Python 2/3 compatibility
  =======================================================

  ``future`` is the missing compatibility layer between Python 2 and Python
  3. It allows you to use a single, clean Python 3.x-compatible codebase to
  support both Python 2 and Python 3 with minimal overhead.

  It is designed to be used as follows::

      from __future__ import (absolute_import, division,
                              print_function, unicode_literals)
      from builtins import (
               bytes, dict, int, list, object, range, str,
               ascii, chr, hex, input, next, oct, open,
               pow, round, super,
               filter, map, zip)

  followed by predominantly standard, idiomatic Python 3 code that then runs
  similarly on Python 2.6/2.7 and Python 3.3+.

  The imports have no effect on Python 3. On Python 2, they shadow the
  corresponding builtins, which normally have different semantics on Python 3
  versus 2, to provide their Python 3 semantics.


  Standard library reorganization
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  ``future`` supports the standard library reorganization (PEP 3108) through the
  following Py3 interfaces:

      >>> # Top-level packages with Py3 names provided on Py2:
      >>> import html.parser
      >>> import queue
      >>> import tkinter.dialog
      >>> import xmlrpc.client
      >>> # etc.

      >>> # Aliases provided for extensions to existing Py2 module names:
      >>> from future.standard_library import install_aliases
      >>> install_aliases()

      >>> from collections import Counter, OrderedDict   # backported to Py2.6
      >>> from collections import UserDict, UserList, UserString
      >>> import urllib.request
      >>> from itertools import filterfalse, zip_longest
      >>> from subprocess import getoutput, getstatusoutput


  Automatic conversion
  --------------------

  An included script called `futurize
  <http://python-future.org/automatic_conversion.html>`_ aids in converting
  code (from either Python 2 or Python 3) to code compatible with both
  platforms. It is similar to ``python-modernize`` but goes further in
  providing Python 3 compatibility through the use of the backported types
  and builtin functions in ``future``.


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

  See: http://python-future.org


  Credits
  -------

  :Author:  Ed Schofield
  :Sponsor: Python Charmers Pty Ltd, Australia, and Python Charmers Pte
            Ltd, Singapore. http://pythoncharmers.com
  :Others:  See docs/credits.rst or http://python-future.org/credits.html


  Licensing
  ---------
  Copyright 2013-2018 Python Charmers Pty Ltd, Australia.
  The software is distributed under an MIT licence. See LICENSE.txt.


pkgId: a36ee3267aa2d874077a7108565228ee2066b3f04c82671a3d7115f702891055
name: rh-python36-google-auth
arch: noarch
version: 1.10.0
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: 0fca7bf3a1f54d84bd63daeb8c15ee52
rpm_sourcerpm: rh-python36-google-auth-1.10.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143529-rh-python36-google-auth/rh-python36-google-auth-1.10.0-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: b926e96ce978ae2ce5eae47c3ce8db490b3bb3fe803799fbfe87cc016c1761e6
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: b947377a95aa45cd8bc281b2bcacbaee
rpm_sourcerpm: rh-python36-humanfriendly-4.18-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00920187-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: 7a602d83e1fd99a81e180abc223da4381060b873f8bf47aed13676e5382f7014
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: fef38251bec24fdb88e64899b0c50af7
rpm_sourcerpm: rh-python36-hyperlink-19.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00914998-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: b35811995a0b7ed96e70806830939a5e0c23d1c91f0c8018f5b5c95cd24549ab
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: a8af1791d96c4b26ac21777b632a4cd4
rpm_sourcerpm: rh-python36-idna-2.9-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01245665-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: bf09b281742d407170eb82d7a636c75dbc16024dd759ebde28be35f768575e0e
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: 4311a4f36ed54cb8b17fb09a30bc02f4
rpm_sourcerpm: rh-python36-importlib_metadata-1.5.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01208545-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: e439f392ed2edc5ab67dec827fdf62b77ddacbcda801d0bbd6a986e83a04a8b7
name: rh-python36-importlib_resources
arch: noarch
version: 1.0.2
epoch: 0
release: 1
summary: Read resources from Python packages
url: http://importlib-resources.readthedocs.io/
rpm_license: Apache Software License
rpm_vendor: Barry Warsaw <barry@python.org>
rpm_group: Development/Libraries
rpm_buildhost: f2dad1760c924e0faff5bf79aa5fb19b
rpm_sourcerpm: rh-python36-importlib_resources-1.0.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143531-rh-python36-importlib_resources/rh-python36-importlib_resources-1.0.2-1.noarch.rpm
checksum_type: sha256
description:
  =========================
   ``importlib_resources``
  =========================

  ``importlib_resources`` is a backport of Python 3.7's standard library
  `importlib.resources
  <https://docs.python.org/3.7/library/importlib.html#module-importlib.resources>`_
  module for Python 2.7, and 3.4 through 3.6.  Users of Python 3.7 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.

  Note that ``pip 10`` is required if you are going to ``pip install
  importlib_resources``.


  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: http://importlib_resources.readthedocs.io/


pkgId: 20537fd2cabe30cc0c642e92803d555994d2fe64d81730e68f242dc17ceecac3
name: rh-python36-incremental
arch: noarch
version: 17.5.0
epoch: 0
release: 1
summary: UNKNOWN
url: https://github.com/twisted/incremental
rpm_license: MIT
rpm_vendor: Amber Brown <hawkowl@twistedmatrix.com>
rpm_group: Development/Libraries
rpm_buildhost: 95ca9fa895314e80a993442c3e0d0f4b
rpm_sourcerpm: rh-python36-incremental-17.5.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879028-rh-python36-incremental/rh-python36-incremental-17.5.0-1.noarch.rpm
checksum_type: sha256
description:
  Incremental
  ===========

  |travis|
  |pypi|
  |coverage|

  Incremental is a small library that versions your Python projects.

  API documentation can be found `here <https://hawkowl.github.io/incremental/docs/>`_.


  Quick Start
  -----------

  Add this to your ``setup.py``\ 's ``setup()`` call, removing any other versioning arguments:

  .. code::

     setup(
         use_incremental=True,
         setup_requires=['incremental'],
         install_requires=['incremental'], # along with any other install dependencies
         ...
     }


  Then run ``python -m incremental.update <projectname> --create`` (you will need ``click`` installed from PyPI).
  It will create a file in your package named ``_version.py`` and look like this:

  .. code::

     from incremental import Version

     __version__ = Version("widgetbox", 17, 1, 0)
     __all__ = ["__version__"]


  Then, so users of your project can find your version, in your root package's ``__init__.py`` add:

  .. code::

     from ._version import __version__


  Subsequent installations of your project will then use Incremental for versioning.


  Incremental Versions
  --------------------

  ``incremental.Version`` is a class that represents a version of a given project.
  It is made up of the following elements (which are given during instantiation):

  - ``package`` (required), the name of the package this ``Version`` represents.
  - ``major``, ``minor``, ``micro`` (all required), the X.Y.Z of your project's ``Version``.
  - ``release_candidate`` (optional), set to 0 or higher to mark this ``Version`` being of a release candidate (also sometimes called a "prerelease").
  - ``dev`` (optional), set to 0 or higher to mark this ``Version`` as a development release.

  You can extract a PEP-440 compatible version string by using the following methods:

  - ``.local()``, which returns a ``str`` containing the full version plus any Git or SVN information, if available. An example output would be ``"17.1.1rc1+r123"`` or ``"3.7.0+rb2e812003b5d5fcf08efd1dffed6afa98d44ac8c"``.
  - ``.public()``, which returns a ``str`` containing the full version, without any Git or SVN information. This is the version you should provide to users, or publicly use. An example output would be ``"13.2.0"``, ``"17.1.2dev1"``, or ``"18.8.0rc2"``.

  Calling ``repr()`` with a ``Version`` will give a Python-source-code representation of it, and calling ``str()`` with a ``Version`` will provide a string similar to ``'[Incremental, version 16.10.1]'``.


  Updating
  --------

  Incremental includes a tool to automate updating your Incremental-using project's version called ``incremental.update``.
  It updates the ``_version.py`` file and automatically updates some uses of Incremental versions from an indeterminate version to the current one.
  It requires ``click`` from PyPI.

  ``python -m incremental.update <projectname>`` will perform updates on that package.
  The commands that can be given after that will determine what the next version is.

  - ``--newversion=<version>``, to set the project version to a fully-specified version (like 1.2.3, or 17.1.0dev1).
  - ``--rc``, to set the project version to ``<year-2000>.<month>.0rc1`` if the current version is not a release candidate, or bump the release candidate number by 1 if it is.
  - ``--dev``, to set the project development release number to 0 if it is not a development release, or bump the development release number by 1 if it is.
  - ``--patch``, to increment the patch number of the release. This will also reset the release candidate number, pass ``--rc`` at the same time to increment the patch number and make it a release candidate.

  If you give no arguments, it will strip the release candidate number, making it a "full release".

  Incremental supports "indeterminate" versions, as a stand-in for the next "full" version. This can be used when the version which will be displayed to the end-user is unknown (for example "introduced in" or "deprecated in"). Incremental supports the following indeterminate versions:

  - ``Version("<projectname>", "NEXT", 0, 0)``
  - ``<projectname> NEXT``

  When you run ``python -m incremental.update <projectname> --rc``, these will be updated to real versions (assuming the target final version is 17.1.0):

  - ``Version("<projectname>", 17, 1, 0, release_candidate=1)``
  - ``<projectname> 17.1.0rc1``

  Once the final version is made, it will become:

  - ``Version("<projectname>", 17, 1, 0)``
  - ``<projectname> 17.1.0``


  .. |coverage| image:: https://codecov.io/github/hawkowl/incremental/coverage.svg?branch=master
  .. _coverage: https://codecov.io/github/hawkowl/incremental

  .. |travis| image:: https://travis-ci.org/hawkowl/incremental.svg?branch=master
  .. _travis: http://travis-ci.org/hawkowl/incremental

  .. |pypi| image:: http://img.shields.io/pypi/v/incremental.svg
  .. _pypi: https://pypi.python.org/pypi/incremental


pkgId: b798470024e0094c3e8d1eb9cf57f89cf041878d853a4b9557d86776de56f37e
name: rh-python36-inflect
arch: noarch
version: 4.0.0
epoch: 0
release: 1
summary: Correctly generate plurals, singular nouns, ordinals, indefinite articles; convert numbers to words
url: http://pypi.python.org/pypi/inflect
rpm_license: UNKNOWN
rpm_vendor: Alex Gronholm <alex.gronholm@nextday.fi>
rpm_group: Development/Libraries
rpm_buildhost: 4e1ab1ce46b34482bd48792b0c16093b
rpm_sourcerpm: rh-python36-inflect-4.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143532-rh-python36-inflect/rh-python36-inflect-4.0.0-1.noarch.rpm
checksum_type: sha256
description:
  ==========
  inflect.py
  ==========

  NAME
  ====

  inflect.py - Correctly generate plurals, singular nouns, ordinals, indefinite articles; convert numbers to words.

  VERSION
  =======

  This document describes version 0.2.4 of inflect.py

  INSTALLATION
  ============

  ``pip install -e git+https://github.com/pwdyson/inflect.py#egg=inflect``

  SYNOPSIS
  ========

  ::

   import inflect
   p = inflect.engine()

   

   
   
   
   
   
   
   
   


   

        print("The plural of ", word, " is ", p.plural(word))


   

        print("I saw", cat_count, p.plural("cat",cat_count))


   

        print(p.plural_noun("I",N1), p.plural_verb("saw",N1), p.plural_adj("my",N2), \)
              p.plural_noun("saw",N2)


   

        print("The singular of ", word, " is ", p.singular_noun(word))

   

        print(p.singular_noun('they')  # 'it')
        p.gender('f')
        print(p.singular_noun('they')  # 'she')


   

        print("There ", p.plural_verb("was",errors), p.no(" error",errors))


   

        print(p.num(N1,""), p.plural("I"), p.plural_verb(" saw"), p.num(N2), p.plural_noun(" saw"))
        print("There ", p.num(errors,''), p.plural_verb("was"), p.no(" error"))


   

        print("same\n"      if p.compare(word1, word2))
        print("same noun\n" if p.compare_nouns(word1, word2))
        print("same verb\n" if p.compare_verbs(word1, word2))
        print("same adj.\n" if p.compare_adjs(word1, word2))


   

        print("Did you want ", p.a(thing), " or ", p.an(idea))


   

        print("It was", p.ordinal(position), " from the left\n")

   
   

      words = p.number_to_words(1234)      # "one thousand, two hundred and thirty-four"
      words = p.number_to_words(p.ordinal(1234)) # "one thousand, two hundred and thirty-fourth"


   

      words = p.number_to_words(1234, getlist=True)    # ("one thousand","two hundred and thirty-four")


   

      words = p.number_to_words(12345, group=1)
      

      words = p.number_to_words(12345, group=2)
      

      words = p.number_to_words(12345, group=3)
      

      words = p.number_to_words(1234, andword='')
      

      words = p.number_to_words(1234, andword=', plus')
      

      words = p.number_to_words(555_1202, group=1, zero='oh')
      

      words = p.number_to_words(555_1202, group=1, one='unity')
      

      words = p.number_to_words(123.456, group=1, decimal='mark')
      

   

      words = p.number_to_words(   9, threshold=10);    # "nine"
      words = p.number_to_words(  10, threshold=10);    # "ten"
      words = p.number_to_words(  11, threshold=10);    # "11"
      words = p.number_to_words(1000, threshold=10);    # "1,000"

   

      mylist = join(("apple", "banana", "carrot"))
          

      mylist = join(("apple", "banana"))
          

      mylist = join(("apple", "banana", "carrot"), final_sep="")
          


   

        p.classical()               # USE ALL CLASSICAL PLURALS

        p.classical(all=True)       # USE ALL CLASSICAL PLURALS
        p.classical(all=False)      # SWITCH OFF CLASSICAL MODE

        p.classical(zero=True)      #  "no error" INSTEAD OF "no errors"
        p.classical(zero=False)     #  "no errors" INSTEAD OF "no error"

        p.classical(herd=True)      #  "2 buffalo" INSTEAD OF "2 buffalos"
        p.classical(herd=False)     #  "2 buffalos" INSTEAD OF "2 buffalo"

        p.classical(persons=True)   # "2 chairpersons" INSTEAD OF "2 chairpeople"
        p.classical(persons=False)  # "2 chairpeople" INSTEAD OF "2 chairpersons"

        p.classical(ancient=True)   # "2 formulae" INSTEAD OF "2 formulas"
        p.classical(ancient=False)  # "2 formulas" INSTEAD OF "2 formulae"



   
   

        print(p.inflect("The plural of {0} is plural({0})".format(word)))
        print(p.inflect("The singular of {0} is singular_noun({0})".format(word)))
        print(p.inflect("I saw {0} plural("cat",{0})".format(cat_count)))
        print(p.inflect("plural(I,{0}) plural_verb(saw,{0}) plural(a,{1}) plural_noun(saw,{1})".format(N1, N2)))
        print(p.inflect("num({0},)plural(I) plural_verb(saw) num({1},)plural(a) plural_noun(saw)".format(N1, N2)))
        print(p.inflect("I saw num({0}) plural("cat")\nnum()".format(cat_count)))
        print(p.inflect("There plural_verb(was,{0}) no(error,{0})".format(errors)))
        print(p.inflect("There num({0},) plural_verb(was) no(error)".format(errors)))
        print(p.inflect("Did you want a({0}) or an({1})".format(thing, idea)))
        print(p.inflect("It was ordinal({0}) from the left".format(position)))


   

        p.defnoun( "VAX", "VAXen" )  # SINGULAR => PLURAL

        p.defverb( "will" , "shall",  # 1ST PERSON SINGULAR => PLURAL
                  "will" , "will",   # 2ND PERSON SINGULAR => PLURAL
                  "will" , "will")   # 3RD PERSON SINGULAR => PLURAL

        p.defadj(  "hir"  , "their")  # SINGULAR => PLURAL

        p.defa("h")        # "AY HALWAYS SEZ 'HAITCH'!"

        p.defan(   "horrendous.*" )    # "AN HORRENDOUS AFFECTATION"


  DESCRIPTION
  ===========

  The methods of the class ``engine`` in module ``inflect.py`` provide plural
  inflections, singular noun inflections, "a"/"an" selection for English words,
  and manipulation of numbers as words.

  Plural forms of all nouns, most verbs, and some adjectives are
  provided. Where appropriate, "classical" variants (for example: "brother" ->
  "brethren", "dogma" -> "dogmata", etc.) are also provided.

  Single forms of nouns are also provided. The gender of singular pronouns
  can be chosen (for example "they" -> "it" or "she" or "he" or "they").

  Pronunciation-based "a"/"an" selection is provided for all English
  words, and most initialisms.

  It is also possible to inflect numerals (1,2,3) to ordinals (1st, 2nd, 3rd)
  and to english words ("one", "two", "three").

  In generating these inflections, ``inflect.py`` follows the Oxford
  English Dictionary and the guidelines in Fowler's Modern English
  Usage, preferring the former where the two disagree.

  The module is built around standard British spelling, but is designed
  to cope with common American variants as well. Slang, jargon, and
  other English dialects are *not* explicitly catered for.

  Where two or more inflected forms exist for a single word (typically a
  "classical" form and a "modern" form), ``inflect.py`` prefers the
  more common form (typically the "modern" one), unless "classical"
  processing has been specified
  (see `MODERN VS CLASSICAL INFLECTIONS`).

  FORMING PLURALS AND SINGULARS
  =============================

  Inflecting Plurals and Singulars
  --------------------------------

  All of the ``plural...`` plural inflection methods take the word to be
  inflected as their first argument and return the corresponding inflection.
  Note that all such methods expect the *singular* form of the word. The
  results of passing a plural form are undefined (and unlikely to be correct).
  Similarly, the ``si...`` singular inflection method expects the *plural*
  form of the word.

  The ``plural...`` methods also take an optional second argument,
  which indicates the grammatical "number" of the word (or of another word
  with which the word being inflected must agree). If the "number" argument is
  supplied and is not ``1`` (or ``"one"`` or ``"a"``, or some other adjective that
  implies the singular), the plural form of the word is returned. If the
  "number" argument *does* indicate singularity, the (uninflected) word
  itself is returned. If the number argument is omitted, the plural form
  is returned unconditionally.

  The ``si...`` method takes a second argument in a similar fashion. If it is
  some form of the number ``1``, or is omitted, the singular form is returned.
  Otherwise the plural is returned unaltered.


  The various methods of ``inflect.engine`` are:



  ``plural_noun(word, count=None)``

   The method ``plural_noun()`` takes a *singular* English noun or
   pronoun and returns its plural. Pronouns in the nominative ("I" ->
   "we") and accusative ("me" -> "us") cases are handled, as are
   possessive pronouns ("mine" -> "ours").


  ``plural_verb(word, count=None)``

   The method ``plural_verb()`` takes the *singular* form of a
   conjugated verb (that is, one which is already in the correct "person"
   and "mood") and returns the corresponding plural conjugation.


  ``plural_adj(word, count=None)``

   The method ``plural_adj()`` takes the *singular* form of
   certain types of adjectives and returns the corresponding plural form.
   Adjectives that are correctly handled include: "numerical" adjectives
   ("a" -> "some"), demonstrative adjectives ("this" -> "these", "that" ->
   "those"), and possessives ("my" -> "our", "cat's" -> "cats'", "child's"
   -> "childrens'", etc.)


  ``plural(word, count=None)``

   The method ``plural()`` takes a *singular* English noun,
   pronoun, verb, or adjective and returns its plural form. Where a word
   has more than one inflection depending on its part of speech (for
   example, the noun "thought" inflects to "thoughts", the verb "thought"
   to "thought"), the (singular) noun sense is preferred to the (singular)
   verb sense.

   Hence ``plural("knife")`` will return "knives" ("knife" having been treated
   as a singular noun), whereas ``plural("knifes")`` will return "knife"
   ("knifes" having been treated as a 3rd person singular verb).

   The inherent ambiguity of such cases suggests that,
   where the part of speech is known, ``plural_noun``, ``plural_verb``, and
   ``plural_adj`` should be used in preference to ``plural``.


  ``singular_noun(word, count=None)``

   The method ``singular_noun()`` takes a *plural* English noun or
   pronoun and returns its singular. Pronouns in the nominative ("we" ->
   "I") and accusative ("us" -> "me") cases are handled, as are
   possessive pronouns ("ours" -> "mine"). When third person
   singular pronouns are returned they take the neuter gender by default
   ("they" -> "it"), not ("they"-> "she") nor ("they" -> "he"). This can be
   changed with ``gender()``.

  Note that all these methods ignore any whitespace surrounding the
  word being inflected, but preserve that whitespace when the result is
  returned. For example, ``plural(" cat  ")`` returns " cats  ".


  ``gender(genderletter)``

   The third person plural pronoun takes the same form for the female, male and
   neuter (e.g. "they"). The singular however, depends upon gender (e.g. "she",
   "he", "it" and "they" -- "they" being the gender neutral form.) By default
   ``singular_noun`` returns the neuter form, however, the gender can be selected with
   the ``gender`` method. Pass the first letter of the gender to
   ``gender`` to return the f(eminine), m(asculine), n(euter) or t(hey)
   form of the singular. e.g.
   gender('f') followed by singular_noun('themselves') returns 'herself'.

  Numbered plurals
  ----------------

  The ``plural...`` methods return only the inflected word, not the count that
  was used to inflect it. Thus, in order to produce "I saw 3 ducks", it
  is necessary to use::

      print("I saw", N, p.plural_noun(animal,N))

  Since the usual purpose of producing a plural is to make it agree with
  a preceding count, inflect.py provides a method
  (``no(word, count)``) which, given a word and a(n optional) count, returns the
  count followed by the correctly inflected word. Hence the previous
  example can be rewritten::

      print("I saw ", p.no(animal,N))

  In addition, if the count is zero (or some other term which implies
  zero, such as ``"zero"``, ``"nil"``, etc.) the count is replaced by the
  word "no". Hence, if ``N`` had the value zero, the previous example
  would print(the somewhat more elegant::)

      I saw no animals

  rather than::

      I saw 0 animals

  Note that the name of the method is a pun: the method
  returns either a number (a *No.*) or a ``"no"``, in front of the
  inflected word.


  Reducing the number of counts required
  --------------------------------------

  In some contexts, the need to supply an explicit count to the various
  ``plural...`` methods makes for tiresome repetition. For example::

      print(plural_adj("This",errors), plural_noun(" error",errors), \)
            plural_verb(" was",errors), " fatal."

  inflect.py therefore provides a method
  (``num(count=None, show=None)``) which may be used to set a persistent "default number"
  value. If such a value is set, it is subsequently used whenever an
  optional second "number" argument is omitted. The default value thus set
  can subsequently be removed by calling ``num()`` with no arguments.
  Hence we could rewrite the previous example::

      p.num(errors)
      print(p.plural_adj("This"), p.plural_noun(" error"), p.plural_verb(" was"), "fatal.")
      p.num()

  Normally, ``num()`` returns its first argument, so that it may also
  be "inlined" in contexts like::

      print(p.num(errors), p.plural_noun(" error"), p.plural_verb(" was"), " detected.")
      if severity > 1:
          print(p.plural_adj("This"), p.plural_noun(" error"), p.plural_verb(" was"), "fatal.")

  However, in certain contexts (see `INTERPOLATING INFLECTIONS IN STRINGS`)
  it is preferable that ``num()`` return an empty string. Hence ``num()``
  provides an optional second argument. If that argument is supplied (that is, if
  it is defined) and evaluates to false, ``num`` returns an empty string
  instead of its first argument. For example::

      print(p.num(errors,0), p.no("error"), p.plural_verb(" was"), " detected.")
      if severity > 1:
          print(p.plural_adj("This"), p.plural_noun(" error"), p.plural_verb(" was"), "fatal.")



  Number-insensitive equality
  ---------------------------

  inflect.py also provides a solution to the problem
  of comparing words of differing plurality through the methods
  ``compare(word1, word2)``, ``compare_nouns(word1, word2)``,
  ``compare_verbs(word1, word2)``, and ``compare_adjs(word1, word2)``.
  Each  of these methods takes two strings, and  compares them
  using the corresponding plural-inflection method (``plural()``, ``plural_noun()``,
  ``plural_verb()``, and ``plural_adj()`` respectively).

  The comparison returns true if:

  - the strings are equal, or
  - one string is equal to a plural form of the other, or
  - the strings are two different plural forms of the one word.


  Hence all of the following return true::

      p.compare("index","index")      # RETURNS "eq"
      p.compare("index","indexes")    # RETURNS "s:p"
      p.compare("index","indices")    # RETURNS "s:p"
      p.compare("indexes","index")    # RETURNS "p:s"
      p.compare("indices","index")    # RETURNS "p:s"
      p.compare("indices","indexes")  # RETURNS "p:p"
      p.compare("indexes","indices")  # RETURNS "p:p"
      p.compare("indices","indices")  # RETURNS "eq"

  As indicated by the comments in the previous example, the actual value
  returned by the various ``compare`` methods encodes which of the
  three equality rules succeeded: "eq" is returned if the strings were
  identical, "s:p" if the strings were singular and plural respectively,
  "p:s" for plural and singular, and "p:p" for two distinct plurals.
  Inequality is indicated by returning an empty string.

  It should be noted that two distinct singular words which happen to take
  the same plural form are *not* considered equal, nor are cases where
  one (singular) word's plural is the other (plural) word's singular.
  Hence all of the following return false::

      p.compare("base","basis")       # ALTHOUGH BOTH -> "bases"
      p.compare("syrinx","syringe")   # ALTHOUGH BOTH -> "syringes"
      p.compare("she","he")           # ALTHOUGH BOTH -> "they"

      p.compare("opus","operas")      # ALTHOUGH "opus" -> "opera" -> "operas"
      p.compare("taxi","taxes")       # ALTHOUGH "taxi" -> "taxis" -> "taxes"

  Note too that, although the comparison is "number-insensitive" it is *not*
  case-insensitive (that is, ``plural("time","Times")`` returns false. To obtain
  both number and case insensitivity, use the ``lower()`` method on both strings
  (that is, ``plural("time".lower(), "Times".lower())`` returns true).


  OTHER VERB FORMS
  ================

  Present participles
  -------------------

  ``inflect.py`` also provides the ``present_participle`` method,
  which can take a 3rd person singular verb and
  correctly inflect it to its present participle::

      p.present_participle("runs")   # "running"
      p.present_participle("loves")  # "loving"
      p.present_participle("eats")   # "eating"
      p.present_participle("bats")   # "batting"
      p.present_participle("spies")  # "spying"


  PROVIDING INDEFINITE ARTICLES
  =============================

  Selecting indefinite articles
  -----------------------------

  inflect.py provides two methods (``a(word, count=None)`` and
  ``an(word, count=None)``) which will correctly prepend the appropriate indefinite
  article to a word, depending on its pronunciation. For example::

      p.a("cat")        # -> "a cat"
      p.an("cat")       # -> "a cat"
      p.a("euphemism")      # -> "a euphemism"
      p.a("Euler number")   # -> "an Euler number"
      p.a("hour")       # -> "an hour"
      p.a("houri")      # -> "a houri"

  The two methods are *identical* in function and may be used
  interchangeably. The only reason that two versions are provided is to
  enhance the readability of code such as::

      print("That is ", an(errortype), " error)
      print("That is ", a(fataltype), " fatal error)

  Note that in both cases the actual article provided depends *only* on
  the pronunciation of the first argument, *not* on the name of the
  method.

  ``a()`` and ``an()`` will ignore any indefinite article that already
  exists at the start of the string. Thus::

      half_arked = [
          "a elephant",
          "a giraffe",
          "an ewe",
          "a orangutan",
      ]

      for txt in half_arked:
          print(p.a(txt))

      
      
      
      
      


  ``a()`` and ``an()`` both take an optional second argument. As with the
  ``plural...`` methods, this second argument is a "number" specifier. If
  its value is ``1`` (or some other value implying singularity), ``a()`` and
  ``an()`` insert "a" or "an" as appropriate. If the number specifier
  implies plurality, (``a()`` and ``an()`` insert the actual second argument instead.
  For example::

      p.a("cat",1)      # -> "a cat"
      p.a("cat",2)      # -> "2 cat"
      p.a("cat","one")      # -> "one cat"
      p.a("cat","no")       # -> "no cat"

  Note that, as implied by the previous examples, ``a()`` and
  ``an()`` both assume that their job is merely to provide the correct
  qualifier for a word (that is: "a", "an", or the specified count).
  In other words, they assume that the word they are given has
  already been correctly inflected for plurality. Hence, if ``N``
  has the value 2, then::

        print(p.a("cat",N))

  prints "2 cat", instead of "2 cats". The correct approach is to use::

        print(p.a(p.plural("cat",N),N))

  or, better still::

        print(p.no("cat",N))

  Note too that, like the various ``plural...`` methods, whenever ``a()``
  and ``an()`` are called with only one argument they are subject to the
  effects of any preceding call to ``num()``. Hence, another possible
  solution is::

        p.num(N)
        print(p.a(p.plural("cat")))


  Indefinite articles and initialisms
  -----------------------------------

  "Initialisms" (sometimes inaccurately called "acronyms") are terms which
  have been formed from the initial letters of words in a phrase (for
  example, "NATO", "NBL", "S.O.S.", "SCUBA", etc.)

  Such terms present a particular challenge when selecting between "a"
  and "an", since they are sometimes pronounced as if they were a single
  word ("nay-tow", "sku-ba") and sometimes as a series of letter names
  ("en-eff-ell", "ess-oh-ess").

  ``a()`` and ``an()`` cope with this dichotomy using a series of inbuilt
  rules, which may be summarized as:



   If the word starts with a single letter, followed by a period or dash
   (for example, "R.I.P.", "C.O.D.", "e-mail", "X-ray", "T-square"), then
   choose the appropriate article for the *sound* of the first letter
   ("an R.I.P.", "a C.O.D.", "an e-mail", "an X-ray", "a T-square").


   If the first two letters of the word are capitals,
   consonants, and do not appear at the start of any known English word,
   (for example, "LCD", "XML", "YWCA"), then once again choose "a" or
   "an" depending on the *sound* of the first letter ("an LCD", "an
   XML", "a YWCA").


   Otherwise, assume the string is a capitalized word or a
   pronounceable initialism (for example, "LED", "OPEC", "FAQ", "UNESCO"), and
   therefore takes "a" or "an" according to the (apparent) pronunciation of
   the entire word ("a LED", "an OPEC", "a FAQ", "a UNESCO").


  Note that rules 1 and 3 together imply that the presence or absence of
  punctuation may change the selection of indefinite article for a
  particular initialism (for example, "a FAQ" but "an F.A.Q.").


  Indefinite articles and "soft H's"
  ----------------------------------

  Words beginning in the letter 'H' present another type of difficulty
  when selecting a suitable indefinite article. In a few such words
  (for example, "hour", "honour", "heir") the 'H' is not voiced at
  all, and so such words inflect with "an". The remaining cases
  ("voiced H's") may be divided into two categories:
  "hard H's" (such as "hangman", "holograph", "hat", etc.) and
  "soft H's" (such as "hysterical", "horrendous", "holy", etc.)

  Hard H's always take "a" as their indefinite article, and soft
  H's normally do so as well. But *some* English speakers prefer
  "an" for soft H's (although the practice is now generally considered an
  affectation, rather than a legitimate grammatical alternative).

  At present, the ``a()`` and ``an()`` methods ignore soft H's and use
  "a" for any voiced 'H'. The author would, however, welcome feedback on
  this decision (envisaging a possible future "soft H" mode).


  INFLECTING ORDINALS
  ===================

  Occasionally it is useful to present an integer value as an ordinal
  rather than as a numeral. For example::

      Enter password (1st attempt): ********
      Enter password (2nd attempt): *********
      Enter password (3rd attempt): *********
      No 4th attempt. Access denied.

  To this end, inflect.py provides the ``ordinal()`` method.
  ``ordinal()`` takes a single argument and forms its ordinal equivalent.
  If the argument isn't a numerical integer, it just adds "-th".


  CONVERTING NUMBERS TO WORDS
  ===========================

  The method ``number_to_words`` takes a number (cardinal or ordinal)
  and returns an English representation of that number.

  ::

      word = p.number_to_words(1234567)

  puts the string::

      "one million, two hundred and thirty-four thousand, five hundred and sixty-seven"

  into ``words``.

  A list can be return where each comma-separated chunk is returned as a separate element.
  Hence::

      words = p.number_to_words(1234567, wantlist=True)

  puts the list::

      ["one million",
       "two hundred and thirty-four thousand",
       "five hundred and sixty-seven"]

  into ``words``.

  Non-digits (apart from an optional leading plus or minus sign,
  any decimal points, and ordinal suffixes -- see below) are silently
  ignored, so the following all produce identical results::

          p.number_to_words(5551202)
          p.number_to_words(5_551_202)
          p.number_to_words("5,551,202")
          p.number_to_words("555-1202")

  That last case is a little awkward since it's almost certainly a phone number,
  and "five million, five hundred and fifty-one thousand, two hundred and two"
  probably isn't what's wanted.

  To overcome this, ``number_to_words()`` takes an optional argument, 'group',
  which changes how numbers are translated. The argument must be a
  positive integer less than four, which indicated how the digits of the
  number are to be grouped. If the argument is ``1``, then each digit is
  translated separately. If the argument is ``2``, pairs of digits
  (starting from the *left*) are grouped together. If the argument is
  ``3``, triples of numbers (again, from the *left*) are grouped. Hence::

          p.number_to_words("555-1202", group=1)

  returns ``"five, five, five, one, two, zero, two"``, whilst::

          p.number_to_words("555-1202", group=2)

  returns ``"fifty-five, fifty-one, twenty, two"``, and::

          p.number_to_words("555-1202", group=3)

  returns ``"five fifty-five, one twenty, two"``.

  Phone numbers are often written in words as
  ``"five..five..five..one..two..zero..two"``, which is also easy to
  achieve::

          join '..', p.number_to_words("555-1202", group=>1)

  ``number_to_words`` also handles decimal fractions. Hence::

          p.number_to_words("1.2345")

  returns ``"one point two three four five"`` in a scalar context
  and ``("one","point","two","three","four","five")``) in an array context.
  Exponent form (``"1.234e56"``) is not yet handled.

  Multiple decimal points are only translated in one of the "grouping" modes.
  Hence::

          p.number_to_words(101.202.303)

  returns ``"one hundred and one point two zero two three zero three"``,
  whereas::

          p.number_to_words(101.202.303, group=1)

  returns ``"one zero one point two zero two point three zero three"``.

  The digit ``'0'`` is unusual in that in may be translated to English as "zero",
  "oh", or "nought". To cater for this diversity, ``number_to_words`` may be passed
  a named argument, 'zero', which may be set to
  the desired translation of ``'0'``. For example::

          print(join "..", p.number_to_words("555-1202", group=3, zero='oh'))

  prints ``"five..five..five..one..two..oh..two"``.
  By default, zero is rendered as "zero".

  Likewise, the digit ``'1'`` may be rendered as "one" or "a/an" (or very
  occasionally other variants), depending on the context. So there is a
  ``'one'`` argument as well::

          for num in [3,2,1,0]:
                print(p.number_to_words(num, one='a solitary', zero='no more'),)
                p.plural(" bottle of beer on the wall", num)

          
          
          
          
          

  Care is needed if the word "a/an" is to be used as a ``'one'`` value.
  Unless the next word is known in advance, it's almost always necessary
  to use the ``A`` function as well::


          for word in ["cat aardvark ewe hour".split()]:
              print(p.a("{0} {1}".format(p.number_to_words(1, one='a'), word)))

      
      
      
      
      

  Another major regional variation in number translation is the use of
  "and" in certain contexts. The named argument 'and'
  allows the programmer to specify how "and" should be handled. Hence::

          print(scalar p.number_to_words("765", andword=''))

  prints "seven hundred sixty-five", instead of "seven hundred and sixty-five".
  By default, the "and" is included.

  The translation of the decimal point is also subject to variation
  (with "point", "dot", and "decimal" being the favorites).
  The named argument 'decimal' allows the
  programmer to how the decimal point should be rendered. Hence::

          print(scalar p.number_to_words("666.124.64.101", group=3, decimal='dot'))

  prints "six sixty-six, dot, one twenty-four, dot, sixty-four, dot, one zero one"
  By default, the decimal point is rendered as "point".

  ``number_to_words`` also handles the ordinal forms of numbers. So::

          print(p.number_to_words('1st'))
          print(p.number_to_words('3rd'))
          print(p.number_to_words('202nd'))
          print(p.number_to_words('1000000th'))

  prints::

          first
          third
          two hundred and twenty-second
          one millionth

  Two common idioms in this regard are::

          print(p.number_to_words(ordinal(number)))

  and::

          print(p.ordinal(p.number_to_words(number)))

  These are identical in effect, except when ``number`` contains a decimal::

          number = 99.09
          print(p.number_to_words(p.ordinal(number));    # ninety-ninth point zero nine)
          print(p.ordinal(p.number_to_words(number));    # ninety-nine point zero ninth)

  Use whichever you feel is most appropriate.


  CONVERTING LISTS OF WORDS TO PHRASES
  ====================================

  When creating a list of words, commas are used between adjacent items,
  except if the items contain commas, in which case semicolons are used.
  But if there are less than two items, the commas/semicolons are omitted
  entirely. The final item also has a conjunction (usually "and" or "or")
  before it. And although it's technically incorrect (and sometimes
  misleading), some people prefer to omit the comma before that final
  conjunction, even when there are more than two items.

  That's complicated enough to warrant its own method: ``join()``.
  This method expects a tuple of words, possibly with one or more
  options. It returns a string that joins the list
  together in the normal English usage. For example::

      print("You chose ", p.join(selected_items))
      

      print("You chose ", p.join(selected_items, final_sep=>""))
      

      print("Please chose ", p.join(side_orders, conj=>"or"))
      

  The available options are::

      Option named    Specifies                Default value

      conj            Final conjunction        "and"
      sep             Inter-item separator     ","
      last_sep        Final separator          value of 'sep' option
      sep_spaced      Space follows sep        True
      conj_spaced     Spaces around conj       True


  INTERPOLATING INFLECTIONS IN STRINGS
  ====================================

  By far the commonest use of the inflection methods is to
  produce message strings for various purposes. For example::

          print(p.num(errors), p.plural_noun(" error"), p.plural_verb(" was"), " detected.")
          if severity > 1:
              print(p.plural_adj("This"), p.plural_noun(" error"), p.plural_verb(" was"), "fatal.")

  Unfortunately the need to separate each method call detracts
  significantly from the readability of the resulting code. To ameliorate
  this problem, inflect.py provides a string-interpolating
  method (``inflect(txt)``), which recognizes calls to the various inflection
  methods within a string and interpolates them appropriately.

  Using ``inflect`` the previous example could be rewritten::

          print(p.inflect("num({0}) plural_noun(error) plural_verb(was) detected.".format(errors)))
          if severity > 1:
              print(p.inflect("plural_adj(This) plural_noun(error) plural_verb(was) fatal."))

  Note that ``inflect`` also correctly handles calls to the ``num()`` method
  (whether interpolated or antecedent). The ``inflect()`` method has
  a related extra feature, in that it *automatically* cancels any "default
  number" value before it returns its interpolated string. This means that
  calls to ``num()`` which are embedded in an ``inflect()``-interpolated
  string do not "escape" and interfere with subsequent inflections.


  MODERN VS CLASSICAL INFLECTIONS
  ===============================

  Certain words, mainly of Latin or Ancient Greek origin, can form
  plurals either using the standard English "-s" suffix, or with
  their original Latin or Greek inflections. For example::

          p.plural("stigma")            # -> "stigmas" or "stigmata"
          p.plural("torus")             # -> "toruses" or "tori"
          p.plural("index")             # -> "indexes" or "indices"
          p.plural("millennium")        # -> "millenniums" or "millennia"
          p.plural("ganglion")          # -> "ganglions" or "ganglia"
          p.plural("octopus")           # -> "octopuses" or "octopodes"


  inflect.py caters to such words by providing an
  "alternate state" of inflection known as "classical mode".
  By default, words are inflected using their contemporary English
  plurals, but if classical mode is invoked, the more traditional
  plural forms are returned instead.

  The method ``classical()`` controls this feature.
  If ``classical()`` is called with no arguments, it unconditionally
  invokes classical mode. If it is called with a single argument, it
  turns all classical inflects on or off (depending on whether the argument is
  true or false). If called with two or more arguments, those arguments
  specify which aspects of classical behaviour are to be used.

  Thus::

          p.classical()                # SWITCH ON CLASSICAL MODE
          print(p.plural("formula")        # -> "formulae")

          p.classical(all=False)               # SWITCH OFF CLASSICAL MODE
          print(p.plural("formula")        # -> "formulas")

          p.classical(cmode=True)           # CLASSICAL MODE IFF cmode
          print(p.plural("formula")        # -> "formulae" (IF cmode))
                                       

          p.classical(herd=True)          # SWITCH ON CLASSICAL MODE FOR "HERD" NOUNS
          print(p.plural("wilderbeest")    # -> "wilderbeest")

          p.classical(names=True)         # SWITCH ON CLASSICAL MODE FOR NAMES
          print(p.plural("sally")          # -> "sallies")
          print(p.plural("Sally")          # -> "Sallys")

  Note however that ``classical()`` has no effect on the inflection of words which
  are now fully assimilated. Hence::

          p.plural("forum")             # ALWAYS -> "forums"
          p.plural("criterion")         # ALWAYS -> "criteria"

  LEI assumes that a capitalized word is a person's name. So it forms the
  plural according to the rules for names (which is that you don't
  inflect, you just add -s or -es). You can choose to turn that behaviour
  off (it's on by the default, even when the module isn't in classical
  mode) by calling `` classical(names=0) ``

  USER-DEFINED INFLECTIONS
  ========================

  Adding plurals at run-time
  --------------------------

  inflect.py provides five methods which allow
  the programmer to override the module's behaviour for specific cases:


  ``defnoun(singular, plural)``

   The ``defnoun`` method takes a pair of string arguments: the singular and the
   plural forms of the noun being specified. The singular form
   specifies a pattern to be interpolated (as ``m/^(?:$first_arg)$/i``).
   Any noun matching this pattern is then replaced by the string in the
   second argument. The second argument specifies a string which is
   interpolated after the match succeeds, and is then used as the plural
   form. For example::

        defnoun( 'cow'        , 'kine')
        defnoun( '(.+i)o'     , '$1i')
        defnoun( 'spam(mer)?' , '\\$\\%\\@#\\$\\@#!!')

   Note that both arguments should usually be specified in single quotes,
   so that they are not interpolated when they are specified, but later (when
   words are compared to them). As indicated by the last example, care
   also needs to be taken with certain characters in the second argument,
   to ensure that they are not unintentionally interpolated during comparison.

   The second argument string may also specify a second variant of the plural
   form, to be used when "classical" plurals have been requested. The beginning
   of the second variant is marked by a '|' character::

        defnoun( 'cow'        , 'cows|kine')
        defnoun( '(.+i)o'     , '$1os|$1i')
        defnoun( 'spam(mer)?' , '\\$\\%\\@#\\$\\@#!!|varmints')

   If no classical variant is given, the specified plural form is used in
   both normal and "classical" modes.


  ..
     

   If the second argument is ``None`` instead of a string, then the
   current user definition for the first argument is removed, and the
   standard plural inflection(s) restored.


   Note that in all cases, later plural definitions for a particular
   singular form replace earlier definitions of the same form. For example::

        
        defnoun( 'aviatrix' , 'aviatrices')

        
        defnoun( 'aviatrix' , 'aviatrixes')

        
        defnoun( 'aviatrix' , undef)


   Special care is also required when defining general patterns and
   associated specific exceptions: put the more specific cases *after*
   the general pattern. For example::

        defnoun( '(.+)us' , '$1i')      # EVERY "-us" TO "-i"
        defnoun( 'bus'    , 'buses')    # EXCEPT FOR "bus"

   This "try-most-recently-defined-first" approach to matching
   user-defined words is also used by ``defverb``, ``defa`` and ``defan``.


  ``defverb(s1, p1, s2, p2, s3, p3)``

   The ``defverb`` method takes three pairs of string arguments (that is, six
   arguments in total), specifying the singular and plural forms of the three
   "persons" of verb. As with ``defnoun``, the singular forms are specifications of
   run-time-interpolated patterns, whilst the plural forms are specifications of
   (up to two) run-time-interpolated strings::

         defverb('am'       , 'are',
                  'are'      , 'are|art",
                  'is'       , 'are')

         defverb('have'     , 'have',
                  'have'     , 'have",
                  'ha(s|th)' , 'have')

   Note that as with ``defnoun``, modern/classical variants of plurals
   may be separately specified, subsequent definitions replace previous
   ones, and ``None``'ed plural forms revert to the standard behaviour.


  ``defadj(singular, plural)``

   The ``defadj`` method takes a pair of string arguments, which specify
   the singular and plural forms of the adjective being defined.
   As with ``defnoun`` and ``defadj``, the singular forms are specifications of
   run-time-interpolated patterns, whilst the plural forms are specifications of
   (up to two) run-time-interpolated strings::

         defadj( 'this'     , 'these')
         defadj( 'red'      , 'red|gules')

   As previously, modern/classical variants of plurals
   may be separately specified, subsequent definitions replace previous
   ones, and ``None``'ed plural forms revert to the standard behaviour.


  ``defa(pattern)`` and ``defan(pattern)``

   The ``defa`` and ``defan`` methods each take a single argument, which
   specifies a pattern. If a word passed to ``a()`` or ``an()`` matches this
   pattern, it will be prefixed (unconditionally) with the corresponding indefinite
   article. For example::

        defa( 'error')
        defa( 'in.+')

        defan('mistake')
        defan('error')

   As with the other ``def_...`` methods, such redefinitions are sequential
   in effect so that, after the above example, "error" will be inflected with "an".


  The ``<$HOME/.inflectrc`` file
  ------------------------------

  THIS HAS NOT BEEN IMPLEMENTED IN THE PYTHON VERSION YET

  When it is imported, inflect.py executes (as Perl code)
  the contents of any file named ``.inflectrc`` which it finds in the
  in the directory where ``Lingua/EN/Inflect.pm`` is installed,
  or in the current home directory (``$ENV{HOME}``), or in both.
  Note that the code is executed within the inflect.py
  namespace.

  Hence the user or the local Perl guru can make appropriate calls to
  ``defnoun``, ``defverb``, etc. in one of these ``.inflectrc`` files, to
  permanently and universally modify the behaviour of the module. For example

        > cat /usr/local/lib/perl5/Text/Inflect/.inflectrc

        defnoun  "UNIX"  => "UN*X|UNICES"

        defverb  "teco"  => "teco",      # LITERALLY: "to edit with TECO"
                  "teco"  => "teco",
                  "tecos" => "teco"

        defa     "Euler.*";              # "Yewler" TURNS IN HIS GRAVE


  Note that calls to the ``def_...`` methods from within a program
  will take precedence over the contents of the home directory
  F<.inflectrc> file, which in turn takes precedence over the system-wide
  F<.inflectrc> file.


  DIAGNOSTICS
  ===========

  THIS HAS NOT BEEN IMPLEMENTED IN THE PYTHON VERSION YET

  On loading, if the Perl code in a ``.inflectrc`` file is invalid
  (syntactically or otherwise), an appropriate fatal error is issued.
  A common problem is not ending the file with something that
  evaluates to true (as the five ``def_...`` methods do).

  Using the five ``def_...`` methods directly in a program may also
  result in fatal diagnostics, if a (singular) pattern or an interpolated
  (plural) string is somehow invalid.

  Specific diagnostics related to user-defined inflections are:


  ``"Bad user-defined singular pattern:\t %s"``

   The singular form of a user-defined noun or verb
   (as defined by a call to ``defnoun``, ``defverb``, ``defadj``,
   ``defa`` or ``defan``) is not a valid Perl regular expression. The
   actual Perl error message is also given.

  ``"Bad user-defined plural string: '%s'"``

   The plural form(s) of a user-defined noun or verb
   (as defined by a call to ``defnoun``, ``defverb`` or ``defadj``)
   is not a valid Perl interpolated string (usually because it
   interpolates some undefined variable).

  ``"Bad .inflectrc file (%s): %s"``

   Some other problem occurred in loading the named local
   or global F<.inflectrc> file. The Perl error message (including
   the line number) is also given.


  There are *no* diagnosable run-time error conditions for the actual
  inflection methods, except ``number_to_words`` and hence no run-time
  diagnostics. If the inflection methods are unable to form a plural
  via a user-definition or an inbuilt rule, they just "guess" the
  commonest English inflection: adding "-s" for nouns, removing "-s" for
  verbs, and no inflection for adjectives.

  ``inflect.py`` can raise the following execeptions:

  ``BadChunkingOptionError``

   The optional argument to ``number_to_words()`` wasn't 1, 2 or 3.

  ``NumOutOfRangeError``

   ``number_to_words()`` was passed a number larger than
   999,999,999,999,999,999,999,999,999,999,999,999 (that is: nine hundred
   and ninety-nine decillion, nine hundred and ninety-nine nonillion, nine
   hundred and ninety-nine octillion, nine hundred and ninety-nine
   septillion, nine hundred and ninety-nine sextillion, nine hundred and
   ninety-nine quintillion, nine hundred and ninety-nine quadrillion, nine
   hundred and ninety-nine trillion, nine hundred and ninety-nine billion,
   nine hundred and ninety-nine million, nine hundred and ninety-nine
   thousand, nine hundred and ninety-nine :-)

   The problem is that ``number_to_words`` doesn't know any
   words for number components bigger than "decillion".


  ..
     

  ``UnknownClassicalModeError``

  ``BadNumValueError``

  ``BadUserDefinedPatternError``

  ``BadRcFileError``


  OTHER ISSUES
  ============

  2nd Person precedence
  ---------------------

  If a verb has identical 1st and 2nd person singular forms, but
  different 1st and 2nd person plural forms, then when its plural is
  constructed, the 2nd person plural form is always preferred.

  The author is not currently aware of any such verbs in English, but is
  not quite arrogant enough to assume *ipso facto* that none exist.


  Nominative precedence
  ---------------------

  The singular pronoun "it" presents a special problem because its plural form
  can vary, depending on its "case". For example::

          It ate my homework       ->  They ate my homework
          It ate it                ->  They ate them
          I fed my homework to it  ->  I fed my homework to them

  As a consequence of this ambiguity, ``plural()`` or ``plural_noun`` have been implemented
  so that they always return the *nominative* plural (that is, "they").

  However, when asked for the plural of an unambiguously *accusative*
  "it" (namely, ``plural("to it")``, ``plural_noun("from it")``, ``plural("with it")``,
  etc.), both methods will correctly return the accusative plural
  ("to them", "from them", "with them", etc.)


  The plurality of zero
  ---------------------

  The rules governing the choice between::

        There were no errors.

  and

  ::

        There was no error.

  are complex and often depend more on *intent* rather than *content*.
  Hence it is infeasible to specify such rules algorithmically.

  Therefore, inflect.py contents itself with the following compromise: If
  the governing number is zero, inflections always return the plural form
  unless the appropriate "classical" inflection is in effect, in which case the
  singular form is always returned.

  Thus, the sequence::

        p.num(0)
        print(p.inflect("There plural(was) no(choice)"))

  produces "There were no choices", whereas::

        p.classical(zero=True)
        p.num(0)
        print(p.inflect("There plural(was) no(choice)"))

  it will print("There was no choice".)


  Homographs with heterogeneous plurals
  -------------------------------------

  Another context in which intent (and not content) sometimes determines
  plurality is where two distinct meanings of a word require different
  plurals. For example::

        Three basses were stolen from the band's equipment trailer.
        Three bass were stolen from the band's aquarium.

        I put the mice next to the cheese.
        I put the mouses next to the computers.

        Several thoughts about leaving crossed my mind.
        Several thought about leaving across my lawn.

  inflect.py handles such words in two ways:


  - If both meanings of the word are the *same* part of speech (for
    example, "bass" is a noun in both sentences above), then one meaning
    is chosen as the "usual" meaning, and only that meaning's plural is
    ever returned by any of the inflection methods.

  - If each meaning of the word is a different part of speech (for
    example, "thought" is both a noun and a verb), then the noun's
    plural is returned by ``plural()`` and ``plural_noun()`` and the verb's plural is
    returned only by ``plural_verb()``.


  Such contexts are, fortunately, uncommon (particularly
  "same-part-of-speech" examples). An informal study of nearly 600
  "difficult plurals" indicates that ``plural()`` can be relied upon to "get
  it right" about 98% of the time (although, of course, ichthyophilic
  guitarists or cyber-behaviouralists may experience higher rates of
  confusion).

  If the choice of a particular "usual inflection" is considered
  inappropriate, it can always be reversed with a preliminary call
  to the corresponding ``def_...`` method.

  NOTE
  ====

  There will be no further correspondence on:

  "octopi".

   Despite the populist pandering of certain New World dictionaries, the
   plural is "octopuses" or (for the pendantic classicist) "octopodes". The
   suffix "-pus" is Greek, not Latin, so the plural is "-podes", not "pi".


  "virus".

   Had no plural in Latin (possibly because it was a mass noun).
   The only plural is the Anglicized "viruses".


  AUTHORS
  =======

  Thorben Krüger (github@benthor.name)
  * established Python 3 compatibility

  Paul Dyson (pwdyson@yahoo.com)
  * converted code from Perl to Python
  * added singular_noun functionality

  Original Perl version of the code and documentation:
  Damian Conway (damian@conway.org),
  Matthew Persico (ORD inflection)


  BUGS AND IRRITATIONS
  ====================

  The endless inconsistencies of English.

  (*Please* report words for which the correct plural or
  indefinite article is not formed, so that the reliability
  of inflect.py can be improved.)



  COPYRIGHT
  =========

      Copyright (C) 2010 Paul Dyson

      Based upon the Perl module Lingua::EN::Inflect by Damian Conway.

      This program is free software: you can redistribute it and/or modify
      it under the terms of the GNU Affero General Public License as published by
      the Free Software Foundation, either version 3 of the License, or
      (at your option) any later version.

      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.

      You should have received a copy of the GNU Affero General Public License
      along with this program.  If not, see <http://www.gnu.org/licenses/>.

      The original Perl module Lingua::EN::Inflect by Damian Conway is
      available from http://search.cpan.org/~dconway/

      This module can be downloaded at http://pypi.python.org/pypi/inflect

      This module can be installed via ``easy_install inflect``

      Repository available at http://github.com/pwdyson/inflect.py


pkgId: b9218a35d537e498aca810a2eec462f331e227f54725270d3f2b15e0f3498b38
name: rh-python36-irc
arch: noarch
version: 17.1
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: 55d6093db7534938bc95a100b4c0ba92
rpm_sourcerpm: rh-python36-irc-17.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143533-rh-python36-irc/rh-python36-irc-17.1-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: c746597058e6bca1355e1b9758a77ea53cafd49d3509bb2ffcbc50f054855a28
name: rh-python36-iso8601
arch: noarch
version: 0.1.12
epoch: 0
release: 1
summary: Simple module to parse ISO 8601 dates
url: https://bitbucket.org/micktwomey/pyiso8601
rpm_license: MIT
rpm_vendor: Michael Twomey <micktwomey+iso8601@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: b35eb26c4fdd46a290a8ab36c67c0927
rpm_sourcerpm: rh-python36-iso8601-0.1.12-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879534-rh-python36-iso8601/rh-python36-iso8601-0.1.12-1.noarch.rpm
checksum_type: sha256
description:
  Simple module to parse ISO 8601 dates

  This module parses the most common forms of ISO 8601 date strings (e.g.
  2007-01-14T20:34:22+00:00) into datetime objects.

  >>> import iso8601
  >>> iso8601.parse_date("2007-01-25T12:00:00Z")
  datetime.datetime(2007, 1, 25, 12, 0, tzinfo=<iso8601.Utc>)
  >>>

  See the LICENSE file for the license this package is released under.

  If you want more full featured parsing look at:

  - http://labix.org/python-dateutil - python-dateutil

  Parsed Formats
  ==============

  You can parse full date + times, or just the date. In both cases a datetime instance is returned but with missing times defaulting to 0, and missing days / months defaulting to 1.

  Dates
  -----

  - YYYY-MM-DD
  - YYYYMMDD
  - YYYY-MM (defaults to 1 for the day)
  - YYYY (defaults to 1 for month and day)

  Times
  -----

  - hh:mm:ss.nn
  - hhmmss.nn
  - hh:mm (defaults to 0 for seconds)
  - hhmm (defaults to 0 for seconds)
  - hh (defaults to 0 for minutes and seconds)

  Time Zones
  ----------

  - Nothing, will use the default timezone given (which in turn defaults to UTC).
  - Z (UTC)
  - +/-hh:mm
  - +/-hhmm
  - +/-hh

  Where it Differs From ISO 8601
  ==============================

  Known differences from the ISO 8601 spec:

  - You can use a " " (space) instead of T for separating date from time.
  - Days and months without a leading 0 (2 vs 02) will be parsed.
  - If time zone information is omitted the default time zone given is used (which in turn defaults to UTC). Use a default of None to yield naive datetime instances.

  Homepage
  ========

  - Documentation: http://pyiso8601.readthedocs.org/
  - Source: https://bitbucket.org/micktwomey/pyiso8601/

  This was originally hosted at https://code.google.com/p/pyiso8601/

  References
  ==========

  - http://en.wikipedia.org/wiki/ISO_8601

  - http://www.cl.cam.ac.uk/~mgk25/iso-time.html - simple overview

  - http://hydracen.com/dx/iso8601.htm - more detailed enumeration of valid formats.

  Testing
  =======

  1. pip install -r dev-requirements.txt
  2. tox

  Note that you need all the pythons installed to perform a tox run (see below). Homebrew helps a lot on the mac, however you wind up having to add cellars to your PATH or symlinking the pythonX.Y executables.

  Alternatively, to test only with your current python:

  1. pip install -r dev-requirements.txt
  2. py.test --verbose iso8601

  Supported Python Versions
  =========================

  Tested against:

  - Python 2.6
  - Python 2.7
  - Python 3.2
  - Python 3.3
  - Python 3.4
  - Python 3.5
  - Python 3.6
  - PyPy
  - PyPy 3

  Python 3.0 and 3.1 are untested but should work (tests didn't run under them when last tried).

  Jython is untested but should work (tests failed to run).

  Python 2.5 is not supported (too old for the tests for the most part). It could work with some small changes but I'm not supporting it.

  Changes
  =======

  0.1.12
  ------

  * Fix class reference for iso8601.Utc in module docstring (thanks to felixschwarz in https://bitbucket.org/micktwomey/pyiso8601/pull-requests/7/fix-class-reference-for-iso8601utc-in/diff)

  0.1.11
  ------

  * Remove logging (thanks to Quentin Pradet in https://bitbucket.org/micktwomey/pyiso8601/pull-requests/6/remove-debug-logging/diff)
  * Add support for , as separator for fractional part (thanks to ecksun in https://bitbucket.org/micktwomey/pyiso8601/pull-requests/5/add-support-for-as-separator-for/diff)
  * Add Python 3.4 and 3.5 to tox test config.
  * Add PyPy 3 to tox test config.
  * Link to documentation at http://pyiso8601.readthedocs.org/


  0.1.10
  ------

  * Fixes https://bitbucket.org/micktwomey/pyiso8601/issue/14/regression-yyyy-mm-no-longer-parses (thanks to Kevin Gill for reporting)
  * Adds YYYY as a valid date (uses 1 for both month and day)
  * Woo, semantic versioning, .10 at last.

  0.1.9
  -----

  * Lots of fixes tightening up parsing from jdanjou. In particular more invalid cases are treated as errors. Also includes fixes for tests (which is how these invalid cases got in in the first place).
  * Release addresses https://bitbucket.org/micktwomey/pyiso8601/issue/13/new-release-based-on-critical-bug-fix

  0.1.8
  -----

  * Remove +/- chars from README.rst and ensure tox tests run using LC_ALL=C. The setup.py egg_info command was failing in python 3.* on some setups (basically any where the system encoding wasn't UTF-8). (https://bitbucket.org/micktwomey/pyiso8601/issue/10/setuppy-broken-for-python-33) (thanks to klmitch)

  0.1.7
  -----

  * Fix parsing of microseconds (https://bitbucket.org/micktwomey/pyiso8601/issue/9/regression-parsing-microseconds) (Thanks to dims and bnemec)

  0.1.6
  -----

  * Correct negative timezone offsets (https://bitbucket.org/micktwomey/pyiso8601/issue/8/015-parses-negative-timezones-incorrectly) (thanks to Jonathan Lange)

  0.1.5
  -----

  * Wow, it's alive! First update since 2007
  * Moved over to https://bitbucket.org/micktwomey/pyiso8601
  * Add support for python 3. https://code.google.com/p/pyiso8601/issues/detail?id=23 (thanks to zefciu)
  * Switched to py.test and tox for testing
  * Make seconds optional in date format ("1997-07-16T19:20+01:00" now valid). https://bitbucket.org/micktwomey/pyiso8601/pull-request/1/make-the-inclusion-of-seconds-optional-in/diff (thanks to Chris Down)
  * Correctly raise ParseError for more invalid inputs (https://bitbucket.org/micktwomey/pyiso8601/issue/1/raise-parseerror-for-invalid-input) (thanks to manish.tomar)
  * Support more variations of ISO 8601 dates, times and time zone specs.
  * Fix microsecond rounding issues (https://bitbucket.org/micktwomey/pyiso8601/issue/2/roundoff-issues-when-parsing-decimal) (thanks to nielsenb@jetfuse.net)
  * Fix pickling and deepcopy of returned datetime objects (https://bitbucket.org/micktwomey/pyiso8601/issue/3/dates-returned-by-parse_date-do-not) (thanks to fogathmann and john@openlearning.com)
  * Fix timezone offsets without a separator (https://bitbucket.org/micktwomey/pyiso8601/issue/4/support-offsets-without-a-separator) (thanks to joe.walton.gglcd)
  * "Z" produces default timezone if one is specified (https://bitbucket.org/micktwomey/pyiso8601/issue/5/z-produces-default-timezone-if-one-is) (thanks to vfaronov). This one may cause problems if you've been relying on default_timezone to use that timezone instead of UTC. Strictly speaking that was wrong but this is potentially backwards incompatible.
  * Handle compact date format (https://bitbucket.org/micktwomey/pyiso8601/issue/6/handle-compact-date-format) (thanks to rvandolson@esri.com)

  0.1.4
  -----

  * The default_timezone argument wasn't being passed through correctly, UTC was being used in every case. Fixes issue 10.

  0.1.3
  -----

  * Fixed the microsecond handling, the generated microsecond values were way too small. Fixes issue 9.

  0.1.2
  -----

  * Adding ParseError to __all__ in iso8601 module, allows people to import it. Addresses issue 7.
  * Be a little more flexible when dealing with dates without leading zeroes. This violates the spec a little, but handles more dates as seen in the field. Addresses issue 6.
  * Allow date/time separators other than T.

  0.1.1
  -----

  * When parsing dates without a timezone the specified default is used. If no default is specified then UTC is used. Addresses issue 4.


pkgId: 704893bb9179e1ed8acc84d2bdab81ac905f3cc04e7f6ba3339a73a714e76869
name: rh-python36-isodate
arch: noarch
version: 0.6.0
epoch: 0
release: 1
summary: An ISO 8601 date/time/duration parser and formatter
url: https://github.com/gweis/isodate/
rpm_license: BSD
rpm_vendor: Gerhard Weis <gerhard.weis@proclos.com>
rpm_group: Development/Libraries
rpm_buildhost: 9c683c2b40b14fd0b2d34a5c919b374d
rpm_sourcerpm: rh-python36-isodate-0.6.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879033-rh-python36-isodate/rh-python36-isodate-0.6.0-1.noarch.rpm
checksum_type: sha256
description:
  ISO 8601 date/time parser
  =========================

  .. image:: https://travis-ci.org/gweis/isodate.svg?branch=master
      :target: https://travis-ci.org/gweis/isodate
      :alt: Travis-CI
  .. image:: https://coveralls.io/repos/gweis/isodate/badge.svg?branch=master
      :target: https://coveralls.io/r/gweis/isodate?branch=master
      :alt: Coveralls
  .. image:: https://img.shields.io/pypi/v/isodate.svg
      :target: https://pypi.python.org/pypi/isodate/
      :alt: Latest Version
  .. image:: https://img.shields.io/pypi/l/isodate.svg
      :target: https://pypi.python.org/pypi/isodate/
      :alt: License


  This module implements ISO 8601 date, time and duration parsing.
  The implementation follows ISO8601:2004 standard, and implements only
  date/time representations mentioned in the standard. If something is not
  mentioned there, then it is treated as non existent, and not as an allowed
  option.

  For instance, ISO8601:2004 never mentions 2 digit years. So, it is not
  intended by this module to support 2 digit years. (while it may still
  be valid as ISO date, because it is not explicitly forbidden.)
  Another example is, when no time zone information is given for a time,
  then it should be interpreted as local time, and not UTC.

  As this module maps ISO 8601 dates/times to standard Python data types, like
  *date*, *time*, *datetime* and *timedelta*, it is not possible to convert
  all possible ISO 8601 dates/times. For instance, dates before 0001-01-01 are
  not allowed by the Python *date* and *datetime* classes. Additionally
  fractional seconds are limited to microseconds. That means if the parser finds
  for instance nanoseconds it will round it to microseconds.

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

  Currently there are four parsing methods available.
     * parse_time:
          parses an ISO 8601 time string into a *time* object
     * parse_date:
          parses an ISO 8601 date string into a *date* object
     * parse_datetime:
          parses an ISO 8601 date-time string into a *datetime* object
     * parse_duration:
          parses an ISO 8601 duration string into a *timedelta* or *Duration*
          object.
     * parse_tzinfo:
          parses the time zone info part of an ISO 8601 string into a
          *tzinfo* object.

  As ISO 8601 allows to define durations in years and months, and *timedelta*
  does not handle years and months, this module provides a *Duration* class,
  which can be used almost like a *timedelta* object (with some limitations).
  However, a *Duration* object can be converted into a *timedelta* object.

  There are also ISO formatting methods for all supported data types. Each
  *xxx_isoformat* method accepts a format parameter. The default format is
  always the ISO 8601 expanded format. This is the same format used by
  *datetime.isoformat*:

      * time_isoformat:
          Intended to create ISO time strings with default format
          *hh:mm:ssZ*.
      * date_isoformat:
          Intended to create ISO date strings with default format
          *yyyy-mm-dd*.
      * datetime_isoformat:
          Intended to create ISO date-time strings with default format
          *yyyy-mm-ddThh:mm:ssZ*.
      * duration_isoformat:
          Intended to create ISO duration strings with default format
          *PnnYnnMnnDTnnHnnMnnS*.
      * tz_isoformat:
          Intended to create ISO time zone strings with default format
          *hh:mm*.
      * strftime:
          A re-implementation mostly compatible with Python's *strftime*, but
          supports only those format strings, which can also be used for dates
          prior 1900. This method also understands how to format *datetime* and
          *Duration* instances.

  Installation:
  -------------

  This module can easily be installed with Python standard installation methods.

  Either use *python setup.py install* or in case you have *setuptools* or
  *distribute* available, you can also use *easy_install*.

  Limitations:
  ------------

     * The parser accepts several date/time representation which should be invalid
       according to ISO 8601 standard.

       1. for date and time together, this parser accepts a mixture of basic and extended format.
          e.g. the date could be in basic format, while the time is accepted in extended format.
          It also allows short dates and times in date-time strings.
       2. For incomplete dates, the first day is chosen. e.g. 19th century results in a date of
          1901-01-01.
       3. negative *Duration* and *timedelta* value are not fully supported yet.

  Further information:
  --------------------

  The doc strings and unit tests should provide rather detailed information about
  the methods and their limitations.

  The source release provides a *setup.py* script,
  which can be used to run the unit tests included.

  Source code is available at `<http://github.com/gweis/isodate>`_.

  CHANGES
  =======

  0.6.0 (2017-10-13)
  ------------------

  - support incomplete month date (Fabien Loffredo)
  - rely on duck typing when doing duration maths
  - support ':' as separator in fractional time zones (usrenmae)


  0.5.4 (2015-08-06)
  ------------------

  - Fix parsing of Periods (Fabien Bochu)
  - Make Duration objects hashable (Geoffrey Fairchild)
  - Add multiplication to duration (Reinoud Elhorst)


  0.5.1 (2014-11-07)
  ------------------

  - fixed pickling of Duration objects
  - raise ISO8601Error when there is no 'T' separator in datetime strings (Adrian Coveney)


  0.5.0 (2014-02-23)
  ------------------

  - ISO8601Error are subclasses of ValueError now (Michael Hrivnak)
  - improve compatibility across various python variants and versions
  - raise exceptions when using fractional years and months in date
    maths with durations
  - renamed method todatetime on Duraction objects to totimedelta


  0.4.9 (2012-10-30)
  ------------------

  - support pickling FixedOffset instances
  - make sure parsed fractional seconds are in microseconds
  - add leading zeros when formattig microseconds (Jarom Loveridge)


  0.4.8 (2012-05-04)
  ------------------

  - fixed incompatibility of unittests with python 2.5 and 2.6 (runs fine on 2.7
    and 3.2)


  0.4.7 (2012-01-26)
  ------------------

  - fixed tzinfo formatting (never pass None into tzinfo.utcoffset())


  0.4.6 (2012-01-06)
  ------------------

  - added Python 3 compatibility via 2to3

  0.4.5 (2012-01-06)
  ------------------

  - made setuptools dependency optional

  0.4.4 (2011-04-16)
  ------------------

  - Fixed formatting of microseconds for datetime objects

  0.4.3 (2010-10-29)
  ------------------

  - Fixed problem with %PATCH formating and fractions (supplied by David Brooks)

  0.4.2 (2010-10-28)
  ------------------

  - Implemented unary - for Duration (supplied by David Brooks)
  - Output fractional seconds with '%PATCH' format. (partly supplied by David Brooks)

  0.4.1 (2010-10-13)
  ------------------

  - fixed bug in comparison between timedelta and Duration.
  - fixed precision problem with microseconds (reported by Tommi Virtanen)

  0.4.0 (2009-02-09)
  ------------------

  - added method to parse ISO 8601 time zone strings
  - added methods to create ISO 8601 conforming strings

  0.3.0 (2009-1-05)
  ------------------

  - Initial release

  TODOs
  =====

  This to do list contains some thoughts and ideas about missing features, and
  parts to think about, whether to implement them or not. This list is probably
  not complete.

  Missing features:
  -----------------

      * time formating does not allow to create fractional representations.
      * parser for ISO intervals.
      * currently microseconds are always padded to a length of 6 characters.
        trailing 0s should be optional

  Documentation:
  --------------

      * parse_datetime:
         - complete documentation to show what this function allows, but ISO forbids.
           and vice verse.
         - support other separators between date and time than 'T'

      * parse_date:
         - yeardigits should be always greater than 4
         - dates before 0001-01-01 are not supported

      * parse_duration:
         - alternative formats are not fully supported due to parse_date restrictions
         - standard duration format is fully supported but not very restrictive.

      * Duration:
         - support fractional years and month in calculations
         - implement w3c order relation? (`<http://www.w3.org/TR/xmlschema-2/#duration-order>`_)
         - refactor to have duration mathematics only at one place.
         - localize __str__ method (does timedelta do this?)
         - when is a Duration negative?
         - normalize Durations. months [00-12] and years ]-inf,+inf[


pkgId: 562fed9d5354b69fcf2e929668d76b8bb4e2db3706b3342accb0a4dc445a149a
name: rh-python36-isort
arch: noarch
version: 4.3.4
epoch: 0
release: 1
summary: A Python utility / library to sort Python imports.
url: https://github.com/timothycrosley/isort
rpm_license: MIT
rpm_vendor: Timothy Crosley <timothy.crosley@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: d43c5edd2a824320a607c3d48526efd5
rpm_sourcerpm: rh-python36-isort-4.3.4-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879034-rh-python36-isort/rh-python36-isort-4.3.4-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://raw.github.com/timothycrosley/isort/master/logo.png
      :alt: isort



  .. image:: https://badge.fury.io/py/isort.svg
      :target: https://badge.fury.io/py/isort
      :alt: PyPI version

  .. image:: https://travis-ci.org/timothycrosley/isort.svg?branch=master
      :target: https://travis-ci.org/timothycrosley/isort
      :alt: Build Status


  .. image:: https://coveralls.io/repos/timothycrosley/isort/badge.svg?branch=release%2F2.6.0&service=github
    :target: https://coveralls.io/github/timothycrosley/isort?branch=release%2F2.6.0
    :alt: Coverage

  .. image:: https://img.shields.io/github/license/mashape/apistatus.svg
      :target: https://pypi.python.org/pypi/hug/
      :alt: License

  .. image:: https://badges.gitter.im/Join%20Chat.svg
     :alt: Join the chat at https://gitter.im/timothycrosley/isort
     :target: https://gitter.im/timothycrosley/isort?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge


  isort your python imports for you so you don't have to.

  isort is a Python utility / library to sort imports alphabetically, and automatically separated into sections.
  It provides a command line utility, Python library and `plugins for various editors <https://github.com/timothycrosley/isort/wiki/isort-Plugins>`_ to quickly sort all your imports.
  It currently cleanly supports Python 2.7 - 3.6 without any dependencies.

  .. image:: https://raw.github.com/timothycrosley/isort/develop/example.gif
     :alt: Example Usage

  Before isort:

  .. code-block:: python

      from my_lib import Object

      print("Hey")

      import os

      from my_lib import Object3

      from my_lib import Object2

      import sys

      from third_party import lib15, lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8, lib9, lib10, lib11, lib12, lib13, lib14

      import sys

      from __future__ import absolute_import

      from third_party import lib3

      print("yo")

  After isort:

  .. code-block:: python

      from __future__ import absolute_import

      import os
      import sys

      from third_party import (lib1, lib2, lib3, lib4, lib5, lib6, lib7, lib8,
                               lib9, lib10, lib11, lib12, lib13, lib14, lib15)

      from my_lib import Object, Object2, Object3

      print("Hey")
      print("yo")

  Installing isort
  ================

  Installing isort is as simple as:

  .. code-block:: bash

      pip install isort

  or if you prefer

  .. code-block:: bash

      easy_install isort

  Using isort
  ===========

  **From the command line**:

  .. code-block:: bash

      isort mypythonfile.py mypythonfile2.py

  or recursively:

  .. code-block:: bash

      isort -rc .

  *which is equivalent to:*

  .. code-block:: bash

      isort **/*.py

  or to see the proposed changes without applying them:

  .. code-block:: bash

      isort mypythonfile.py --diff

  Finally, to atomically run isort against a project, only applying changes if they don't introduce syntax errors do:

  .. code-block:: bash

      isort -rc --atomic .

  (Note: this is disabled by default as it keeps isort from being able to run against code written using a different version of Python)

  **From within Python**:

  .. code-block:: bash

      from isort import SortImports

      SortImports("pythonfile.py")

  or:

  .. code-block:: bash

      from isort import SortImports

      new_contents = SortImports(file_contents=old_contents).output

  **From within Kate:**

  .. code-block:: bash

      ctrl+[

  or:

  .. code-block:: bash

      menu > Python > Sort Imports

  Installing isort's Kate plugin
  ==============================

  For KDE 4.13+ / Pate 2.0+:

  .. code-block:: bash

      wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin.py --output-document ~/.kde/share/apps/kate/pate/isort_plugin.py
      wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin_ui.rc --output-document ~/.kde/share/apps/kate/pate/isort_plugin_ui.rc
      wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/katepart_isort.desktop --output-document ~/.kde/share/kde4/services/katepart_isort.desktop

  For all older versions:

  .. code-block:: bash

      wget https://raw.github.com/timothycrosley/isort/master/kate_plugin/isort_plugin_old.py --output-document ~/.kde/share/apps/kate/pate/isort_plugin.py

  You will then need to restart kate and enable Python Plugins as well as the isort plugin itself.

  Installing isort's for your preferred text editor
  =================================================

  Several plugins have been written that enable to use isort from within a variety of text-editors.
  You can find a full list of them `on the isort wiki <https://github.com/timothycrosley/isort/wiki/isort-Plugins>`_.
  Additionally, I will enthusiastically accept pull requests that include plugins for other text editors
  and add documentation for them as I am notified.

  How does isort work?
  ====================

  isort parses specified files for global level import lines (imports outside of try / except blocks, functions, etc..)
  and puts them all at the top of the file grouped together by the type of import:

  - Future
  - Python Standard Library
  - Third Party
  - Current Python Project
  - Explicitly Local (. before import, as in: ``from . import x``)
  - Custom Separate Sections (Defined by forced_separate list in configuration file)
  - Custom Sections (Defined by sections list in configuration file)

  Inside of each section the imports are sorted alphabetically. isort automatically removes duplicate python imports,
  and wraps long from imports to the specified line length (defaults to 80).

  When will isort not work?
  =========================

  If you ever have the situation where you need to have a try / except block in the middle of top-level imports or if
  your import order is directly linked to precedence.

  For example: a common practice in Django settings files is importing * from various settings files to form
  a new settings file. In this case if any of the imports change order you are changing the settings definition itself.

  However, you can configure isort to skip over just these files - or even to force certain imports to the top.

  Configuring isort
  =================

  If you find the default isort settings do not work well for your project, isort provides several ways to adjust
  the behavior.

  To configure isort for a single user create a ``~/.isort.cfg`` file:

  .. code-block:: ini

      [settings]
      line_length=120
      force_to_top=file1.py,file2.py
      skip=file3.py,file4.py
      known_future_library=future,pies
      known_standard_library=std,std2
      known_third_party=randomthirdparty
      known_first_party=mylib1,mylib2
      indent='    '
      multi_line_output=3
      length_sort=1
      forced_separate=django.contrib,django.utils
      default_section=FIRSTPARTY
      no_lines_before=LOCALFOLDER

  Additionally, you can specify project level configuration simply by placing a ``.isort.cfg`` file at the root of your
  project. isort will look up to 25 directories up, from the file it is ran against, to find a project specific configuration.

  Or, if you prefer, you can add an isort section to your project's ``setup.cfg`` or ``tox.ini`` file with any desired settings.

  You can then override any of these settings by using command line arguments, or by passing in override values to the
  SortImports class.

  Finally, as of version 3.0 isort supports editorconfig files using the standard syntax defined here:
  http://editorconfig.org/

  Meaning you place any standard isort configuration parameters within a .editorconfig file under the ``*.py`` section
  and they will be honored.

  For a full list of isort settings and their meanings `take a look at the isort wiki <https://github.com/timothycrosley/isort/wiki/isort-Settings>`_.

  Multi line output modes
  =======================

  You will notice above the "multi_line_output" setting. This setting defines how from imports wrap when they extend
  past the line_length limit and has 6 possible settings:

  **0 - Grid**

  .. code-block:: python

      from third_party import (lib1, lib2, lib3,
                               lib4, lib5, ...)

  **1 - Vertical**

  .. code-block:: python

      from third_party import (lib1,
                               lib2,
                               lib3
                               lib4,
                               lib5,
                               ...)

  **2 - Hanging Indent**

  .. code-block:: python

      from third_party import \
          lib1, lib2, lib3, \
          lib4, lib5, lib6

  **3 - Vertical Hanging Indent**

  .. code-block:: python

      from third_party import (
          lib1,
          lib2,
          lib3,
          lib4,
      )

  **4 - Hanging Grid**

  .. code-block:: python

      from third_party import (
          lib1, lib2, lib3, lib4,
          lib5, ...)

  **5 - Hanging Grid Grouped**

  .. code-block:: python

      from third_party import (
          lib1, lib2, lib3, lib4,
          lib5, ...
      )

  **6 - NOQA**

  .. code-block:: python

      from third_party import lib1, lib2, lib3, ...  # NOQA

  Alternatively, you can set ``force_single_line`` to ``True`` (``-sl`` on the command line) and every import will appear on its
  own line:

  .. code-block:: python

      from third_party import lib1
      from third_party import lib2
      from third_party import lib3
      ...

  Note: to change the how constant indents appear - simply change the indent property with the following accepted formats:
  *   Number of spaces you would like. For example: 4 would cause standard 4 space indentation.
  *   Tab
  *   A verbatim string with quotes around it.

  For example:

  .. code-block:: python

      "    "

  is equivalent to 4.

  For the import styles that use parentheses, you can control whether or not to
  include a trailing comma after the last import with the ``include_trailing_comma``
  option (defaults to ``False``).

  Intelligently Balanced Multi-line Imports
  =========================================

  As of isort 3.1.0 support for balanced multi-line imports has been added.
  With this enabled isort will dynamically change the import length to the one that produces the most balanced grid,
  while staying below the maximum import length defined.

  Example:

  .. code-block:: python

      from __future__ import (absolute_import, division,
                              print_function, unicode_literals)

  Will be produced instead of:

  .. code-block:: python

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)

  To enable this set ``balanced_wrapping`` to ``True`` in your config or pass the ``-e`` option into the command line utility.

  Custom Sections and Ordering
  ============================

  You can change the section order with ``sections`` option from the default of:

  .. code-block:: ini

      FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER

  to your preference:

  .. code-block:: ini

      sections=FUTURE,STDLIB,FIRSTPARTY,THIRDPARTY,LOCALFOLDER

  You also can define your own sections and their order.

  Example:

  .. code-block:: ini

      known_django=django
      known_pandas=pandas,numpy
      sections=FUTURE,STDLIB,DJANGO,THIRDPARTY,PANDAS,FIRSTPARTY,LOCALFOLDER

  would create two new sections with the specified known modules.

  The ``no_lines_before`` option will prevent the listed sections from being split from the previous section by an empty line.

  Example:

  .. code-block:: ini

     sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
     no_lines_before=LOCALFOLDER

  would produce a section with both FIRSTPARTY and LOCALFOLDER modules combined.

  Auto-comment import sections
  ============================

  Some projects prefer to have import sections uniquely titled to aid in identifying the sections quickly
  when visually scanning. isort can automate this as well. To do this simply set the ``import_heading_{section_name}``
  setting for each section you wish to have auto commented - to the desired comment.

  For Example:

  .. code-block:: ini

      import_heading_stdlib=Standard Library
      import_heading_firstparty=My Stuff

  Would lead to output looking like the following:

  .. code-block:: python

      
      import os
      import sys

      import django.settings

      
      import myproject.test

  Ordering by import length
  =========================

  isort also makes it easy to sort your imports by length, simply by setting the ``length_sort`` option to ``True``.
  This will result in the following output style:

  .. code-block:: python

      from evn.util import (
          Pool,
          Dict,
          Options,
          Constant,
          DecayDict,
          UnexpectedCodePath,
      )

  Skip processing of imports (outside of configuration)
  =====================================================

  To make isort ignore a single import simply add a comment at the end of the import line containing the text ``isort:skip``:

  .. code-block:: python

      import module  # isort:skip

  or:

  .. code-block:: python

      from xyz import (abc,  # isort:skip
                       yo,
                       hey)

  To make isort skip an entire file simply add ``isort:skip_file`` to the module's doc string:

  .. code-block:: python

      """ my_module.py
          Best module ever

         isort:skip_file
      """

      import b
      import a

  Adding an import to multiple files
  ==================================

  isort makes it easy to add an import statement across multiple files, while being assured it's correctly placed.

  From the command line:

  .. code-block:: bash

      isort -a "from __future__ import print_function" *.py

  from within Kate:

  .. code-block::

      ctrl+]

  or:

  .. code-block::

      menu > Python > Add Import

  Removing an import from multiple files
  ======================================

  isort also makes it easy to remove an import from multiple files, without having to be concerned with how it was originally
  formatted.

  From the command line:

  .. code-block:: bash

      isort -r "os.system" *.py

  from within Kate:

  .. code-block::

      ctrl+shift+]

  or:

  .. code-block::

      menu > Python > Remove Import

  Using isort to verify code
  ==========================

  The ``--check-only`` option
  ---------------------------

  isort can also be used to used to verify that code is correctly formatted by running it with ``-c``.
  Any files that contain incorrectly sorted and/or formatted imports will be outputted to ``stderr``.

  .. code-block:: bash

      isort **/*.py -c -vb

      SUCCESS: /home/timothy/Projects/Open_Source/isort/isort_kate_plugin.py Everything Looks Good!
      ERROR: /home/timothy/Projects/Open_Source/isort/isort/isort.py Imports are incorrectly sorted.

  One great place this can be used is with a pre-commit git hook, such as this one by @acdha:

  https://gist.github.com/acdha/8717683

  This can help to ensure a certain level of code quality throughout a project.


  Git hook
  --------

  isort provides a hook function that can be integrated into your Git pre-commit script to check
  Python code before committing.

  To cause the commit to fail if there are isort errors (strict mode), include the following in
  ``.git/hooks/pre-commit``:

  .. code-block:: python

      
      import sys
      from isort.hooks import git_hook

      sys.exit(git_hook(strict=True))

  If you just want to display warnings, but allow the commit to happen anyway, call ``git_hook`` without
  the `strict` parameter.

  Setuptools integration
  ----------------------

  Upon installation, isort enables a ``setuptools`` command that checks Python files
  declared by your project.

  Running ``python setup.py isort`` on the command line will check the files
  listed in your ``py_modules`` and ``packages``.  If any warning is found,
  the command will exit with an error code:

  .. code-block:: bash

      $ python setup.py isort

  Also, to allow users to be able to use the command without having to install
  isort themselves, add isort to the setup_requires of your ``setup()`` like so:

  .. code-block:: python

      setup(
          name="project",
          packages=["project"],

          setup_requires=[
              "isort"
          ]
      )


  Why isort?
  ==========

  isort simply stands for import sort. It was originally called "sortImports" however I got tired of typing the extra
  characters and came to the realization camelCase is not pythonic.

  I wrote isort because in an organization I used to work in the manager came in one day and decided all code must
  have alphabetically sorted imports. The code base was huge - and he meant for us to do it by hand. However, being a
  programmer - I'm too lazy to spend 8 hours mindlessly performing a function, but not too lazy to spend 16
  hours automating it. I was given permission to open source sortImports and here we are :)

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

  Thanks and I hope you find isort useful!

  ~Timothy Crosley


pkgId: a825be10e1ededb2113755537622b1540003b0397fe384e56d99f8e2de389a4a
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: 04c5324080824022a62149f6cecbabca
rpm_sourcerpm: rh-python36-itsdangerous-1.1.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00887848-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: 3678dc134f39dbb1f35b158155c4d551bcc78bd211551b892d7394024dc79f6f
name: rh-python36-jaraco.classes
arch: noarch
version: 2.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: 5dff8947af69470c8a705acc2d1bee42
rpm_sourcerpm: rh-python36-jaraco.classes-2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879035-rh-python36-jaraco.classes/rh-python36-jaraco.classes-2.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: e16104acc7c34de48069137d484cbe1a7bd4f07d22d897ce4aed1902dffa06a9
name: rh-python36-jaraco.collections
arch: noarch
version: 2.1
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: 7f7ff40ba87c403faaff618fc3d47275
rpm_sourcerpm: rh-python36-jaraco.collections-2.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143534-rh-python36-jaraco.collections/rh-python36-jaraco.collections-2.1-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: 9afca406a82ee908eee46f318eedfc98c23a33b5413b703df2fc14bf878d61ad
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: d2ae507dea8246ee856f354321a0de11
rpm_sourcerpm: rh-python36-jaraco.functools-3.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143890-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: 6cc014a704eac991cb656b3d2bbe2ad8652b2a610eed98ad2656aa4eb29543c7
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: 4b61af0398cc4e3abf8b2a64fd9df9ed
rpm_sourcerpm: rh-python36-jaraco.itertools-4.4.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00914999-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: b8361ecd2f59271fc9dd091b8c40482940d9798d985c85db03bc416a33a1ecaa
name: rh-python36-jaraco.logging
arch: noarch
version: 2.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: 02d1f20ff45e4d8c88ed87cb2f286604
rpm_sourcerpm: rh-python36-jaraco.logging-2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879039-rh-python36-jaraco.logging/rh-python36-jaraco.logging-2.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: 4acbe397e00dca58547c55d215df3fee09a1e86bc059deffd982c2492c1ea674
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: 0cac5c2bfb6e4c6d9e4662f0989a0bd1
rpm_sourcerpm: rh-python36-jaraco.stream-3.0.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143535-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: 983bdb1da01ea1a86cce61b7c40dc284b89e393261982174f88c5007ffb0c641
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: 4bdbfa5130f947fbaf317d39e91f611c
rpm_sourcerpm: rh-python36-jaraco.text-3.2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143802-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: b607c95a58754a2c5d16637118e0dba15e02ae252fa4d94e4d6be8bd63659339
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: c2e59cc69610475ab50c0ab6d97a3bcc
rpm_sourcerpm: rh-python36-jmespath-0.9.4-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879042-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: c775e79bf1703c4c80075cdc47fc93cd9991bc9d0886f696b5deec83461fbb21
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: b558d9778ba74d5da4208440891bb8a4
rpm_sourcerpm: rh-python36-jsonpatch-1.25-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01225014-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: 252ab7f94acf4167e825c7546d1b173ec8a38075e057a0163e7feeda62c76f57
name: rh-python36-jsonpointer
arch: noarch
version: 2.0
epoch: 0
release: 1
summary: Identify specific nodes in a JSON document (RFC 6901)
url: https://github.com/stefankoegl/python-json-pointer
rpm_license: Modified BSD License
rpm_vendor: Stefan Kögl <stefan@skoegl.net>
rpm_group: Development/Libraries
rpm_buildhost: 08ac8f70fe5844b1adac3ddc8bb9d5e2
rpm_sourcerpm: rh-python36-jsonpointer-2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879046-rh-python36-jsonpointer/rh-python36-jsonpointer-2.0-1.noarch.rpm
checksum_type: sha256
description:
  python-json-pointer
  ===================

  [![PyPI version](https://img.shields.io/pypi/v/jsonpointer.svg)](https://pypi.python.org/pypi/jsonpointer/)
  [![Supported Python versions](https://img.shields.io/pypi/pyversions/jsonpointer.svg)](https://pypi.python.org/pypi/jsonpointer/)
  [![Build Status](https://travis-ci.org/stefankoegl/python-json-pointer.png?branch=master)](https://travis-ci.org/stefankoegl/python-json-pointer)
  [![Coverage Status](https://coveralls.io/repos/stefankoegl/python-json-pointer/badge.png?branch=master)](https://coveralls.io/r/stefankoegl/python-json-pointer?branch=master)


  Resolve JSON Pointers in Python
  -------------------------------

  Library to resolve JSON Pointers according to
  [RFC 6901](http://tools.ietf.org/html/rfc6901)

  See source code for examples
  * Website: https://github.com/stefankoegl/python-json-pointer
  * Repository: https://github.com/stefankoegl/python-json-pointer.git
  * Documentation: https://python-json-pointer.readthedocs.org/
  * PyPI: https://pypi.python.org/pypi/jsonpointer
  * Travis CI: https://travis-ci.org/stefankoegl/python-json-pointer
  * Coveralls: https://coveralls.io/r/stefankoegl/python-json-pointer


pkgId: 630d11f1995b4d1a17fe7c9961000739c384d9bb3f2af33d44aecdbc6326c156
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: 3aca1018d7594a0e8d5d91fe39bb6e4f
rpm_sourcerpm: rh-python36-jsonschema-3.2.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143804-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: a7c6fb691c6d6206125895bcc5e5429f73e2646fc156bbcb85f7cf4cf85873dd
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: 274948c344ec417c85d59f4567e135f4
rpm_sourcerpm: rh-python36-junit-xml-1.8-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00887793-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: c3a52ecaf4634b68cd9f8261c3905b5c70bd29e83438b915aa48a0110402c9b7
name: rh-python36-keyring
arch: noarch
version: 15.1.0
epoch: 0
release: 1
summary: Store and access your passwords safely.
url: https://github.com/jaraco/keyring
rpm_license: UNKNOWN
rpm_vendor: Jason R. Coombs <jaraco@jaraco.com>
rpm_group: Development/Libraries
rpm_buildhost: 78a908ebf08e4bc181115c1ccae86c67
rpm_sourcerpm: rh-python36-keyring-15.1.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879524-rh-python36-keyring/rh-python36-keyring-15.1.0-1.noarch.rpm
checksum_type: sha256
description:
  .. image:: https://img.shields.io/pypi/v/keyring.svg
     :target: https://pypi.org/project/keyring

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

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

  .. .. image:: https://img.shields.io/appveyor/ci/jaraco/keyring/master.svg
  ..    :target: https://ci.appveyor.com/project/jaraco/keyring/branch/master

  .. image:: https://readthedocs.org/projects/keyring/badge/?version=latest
     :target: https://keyring.readthedocs.io/en/latest/?badge=latest

  =======================================
  Installing and Using Python Keyring Lib
  =======================================

  .. contents:: **Table of Contents**

  ---------------------------
  What is Python keyring lib?
  ---------------------------

  The Python keyring lib provides an easy way to access the system keyring service
  from python. It can be used in any application that needs safe password storage.

  The keyring library is licensed under both the `MIT license
  <http://opensource.org/licenses/MIT>`_ and the PSF license.

  These recommended keyring backends are supported by the Python keyring lib:

  * macOS `Keychain
    <https://en.wikipedia.org/wiki/Keychain_%28software%29>`_
  * Freedesktop `Secret Service
    <http://standards.freedesktop.org/secret-service/>`_ supports many DE including
    GNOME (requires `secretstorage <https://pypi.python.org/pypi/secretstorage>`_)
  * KDE4 & KDE5 `KWallet <https://en.wikipedia.org/wiki/KWallet>`_
    (requires `dbus <https://pypi.python.org/pypi/dbus-python>`_)
  * `Windows Credential Locker
    <https://docs.microsoft.com/en-us/windows/uwp/security/credential-locker>`_

  Other keyring implementations are available through `Third-Party Backends`_.

  -------------------------
  Installation Instructions
  -------------------------

  Install from Index
  ==================

  Install using your favorite installer. For example:

      $ pip install keyring

  Linux
  -----

  On Linux, the recommended keyring relies on SecretStorage, which in
  turn relies on dbus-python, but dbus-python does not install correctly
  when using the Python installers, so dbus-python must be installed
  as a system package. See `the SecretStorage GitHub repo
  <https://github.com/mitya57/secretstorage>`_ for details.

  -------------
  Using Keyring
  -------------

  The basic usage of keyring is pretty simple: just call `keyring.set_password`
  and `keyring.get_password`:

      >>> import keyring
      >>> keyring.set_password("system", "username", "password")
      >>> keyring.get_password("system", "username")
      'password'

  Command-line Utility
  ====================

  Keyring supplies a ``keyring`` command which is installed with the
  package. After installing keyring in most environments, the
  command should be available for setting, getting, and deleting
  passwords. For more information on usage, invoke with no arguments
  or with ``--help`` as so::

      $ keyring --help
      $ keyring set system username
      Password for 'username' in 'system':
      $ keyring get system username
      password

  The command-line functionality is also exposed as an executable
  package, suitable for invoking from Python like so::

      $ python -m keyring --help
      $ python -m keyring set system username
      Password for 'username' in 'system':
      $ python -m keyring get system username
      password

  --------------------------
  Configure your keyring lib
  --------------------------

  The python keyring lib contains implementations for several backends. The
  library will
  automatically choose the keyring that is most suitable for your current
  environment. You can also specify the keyring you like to be used in the
  config file or by calling the ``set_keyring()`` function.

  Customize your keyring by config file
  =====================================

  This section describes how to change your option in the config file.

  Config file path
  ----------------

  The configuration of the lib is stored in a file named "keyringrc.cfg". This
  file must be found in a platform-specific location. To determine
  where the config file is stored, run the following::

      python -c "import keyring.util.platform_; print(keyring.util.platform_.config_root())"

  Some keyrings also store the keyring data in the file system. To determine
  where the data files are stored, run this command::

      python -c "import keyring.util.platform_; print(keyring.util.platform_.data_root())"


  Config file content
  -------------------

  To specify a keyring backend, set the **default-keyring** option to the
  full path of the class for that backend, such as
  ``keyring.backends.OS_X.Keyring``.

  If **keyring-path** is indicated, keyring will add that path to the Python
  module search path before loading the backend.

  For example, this config might be used to load the SimpleKeyring from the demo
  directory in the project checkout::

      [backend]
      default-keyring=simplekeyring.SimpleKeyring
      keyring-path=/home/kang/pyworkspace/python-keyring-lib/demo/

  Third-Party Backends
  ====================

  In addition to the backends provided by the core keyring package for
  the most common and secure use cases, there
  are additional keyring backend implementations available for other
  use-cases. Simply install them to make them available:

  - `keyrings.cryptfile <https://pypi.org/project/keyrings.cryptfile>`_
    - Encrypted text file storage.
  - `keyring_jeepney <https://pypi.org/project/keyring_jeepney>`__ - a
    pure Python backend using the secret service DBus API for desktop
    Linux.
  - `keyrings.alt <https://pypi.org/project/keyrings.alt>`_ - "alternate",
    possibly-insecure backends, originally part of the core package, but
    available for opt-in.
  - `gsheet-keyring <https://pypi.org/project/gsheet-keyring>`_
    - a backend that stores secrets in a Google Sheet. For use with
    `ipython-secrets <https://pypi.org/project/ipython-secrets>`_.

  Write your own keyring backend
  ==============================

  The interface for the backend is defined by ``keyring.backend.KeyringBackend``.
  Every backend should derive from that base class and define a ``priority``
  attribute and three functions: ``get_password()``, ``set_password()``, and
  ``delete_password()``.

  See the ``backend`` module for more detail on the interface of this class.

  Keyring employs entry points to allow any third-party package to implement
  backends without any modification to the keyring itself. Those interested in
  creating new backends are encouraged to create new, third-party packages
  in the ``keyrings`` namespace, in a manner modeled by the `keyrings.alt
  package <https://github.com/jaraco/keyrings.alt>`_. See the ``setup.py`` file
  in that project for a hint on how to create the requisite entry points.
  Backends that prove essential may be considered for inclusion in the core
  library, although the ease of installing these third-party packages should
  mean that extensions may be readily available.

  If you've created an extension for Keyring, please submit a pull request to
  have your extension mentioned as an available extension.

  Set the keyring in runtime
  ==========================

  Keyring additionally allows programmatic configuration of the
  backend calling the api ``set_keyring()``. The indicated backend
  will subsequently be used to store and retrieve passwords.

  Here's an example demonstrating how to invoke ``set_keyring``::

      
      import keyring.backend

      class TestKeyring(keyring.backend.KeyringBackend):
          """A test keyring which always outputs same password
          """
          priority = 1

          def set_password(self, servicename, username, password):
              pass

          def get_password(self, servicename, username):
              return "password from TestKeyring"

          def delete_password(self, servicename, username, password):
              pass

      
      keyring.set_keyring(TestKeyring())

      
      try:
          keyring.set_password("demo-service", "tarek", "passexample")
          print("password stored successfully")
      except keyring.errors.PasswordSetError:
          print("failed to store password")
      print("password", keyring.get_password("demo-service", "tarek"))


  Using Keyring on Ubuntu 16.04
  =============================

  The following is a complete transcript for installing keyring in a
  virtual environment on Ubuntu 16.04.  No config file was used.::

    $ sudo apt install python3-venv libdbus-glib-1-dev
    $ cd /tmp
    $ pyvenv py3
    $ source py3/bin/activate
    $ pip install -U pip
    $ pip install secretstorage dbus-python
    $ pip install keyring
    $ python
    >>> import keyring
    >>> keyring.get_keyring()
    <keyring.backends.SecretService.Keyring object at 0x7f9b9c971ba8>
    >>> keyring.set_password("system", "username", "password")
    >>> keyring.get_password("system", "username")
    'password'


  Using Keyring on headless Linux systems
  =======================================

  It is possible to use the SecretService backend on Linux systems without
  X11 server available (only D-Bus is required). To do that, you need the
  following:

  * Install the `GNOME Keyring`_ daemon.
  * Start a D-Bus session, e.g. run ``dbus-run-session -- sh`` and run
    the following commands inside that shell.
  * Run ``gnome-keyring-daemon`` with ``--unlock`` option. The description of
    that option says:

        Read a password from stdin, and use it to unlock the login keyring
        or create it if the login keyring does not exist.

    When that command is started, enter your password into stdin and
    press Ctrl+D (end of data). After that the daemon will fork into
    background (use ``--foreground`` option to prevent that).
  * Now you can use the SecretService backend of Keyring. Remember to
    run your application in the same D-Bus session as the daemon.

  .. _GNOME Keyring: https://wiki.gnome.org/Projects/GnomeKeyring

  -----------------------------------------------
  Integrate the keyring lib with your application
  -----------------------------------------------

  API interface
  =============

  The keyring lib has a few functions:

  * ``get_keyring()``: Return the currently-loaded keyring implementation.
  * ``get_password(service, username)``: Returns the password stored in the
    active keyring. If the password does not exist, it will return None.
  * ``set_password(service, username, password)``: Store the password in the
    keyring.
  * ``delete_password(service, username)``: Delete the password stored in
    keyring. If the password does not exist, it will raise an exception.

  In all cases, the parameters (``service``, ``username``, ``password``)
  should be Unicode text. On Python 2, these parameters are accepted as
  simple ``str`` in the default encoding as they will be implicitly
  decoded to text. Some backends may accept ``bytes`` for these parameters,
  but such usage is discouraged.


  Exceptions
  ==========

  The keyring lib raises following exceptions:

  * ``keyring.errors.KeyringError``: Base Error class for all exceptions in keyring lib.
  * ``keyring.errors.InitError``: Raised when the keyring can't be initialized.
  * ``keyring.errors.PasswordSetError``: Raise when password can't be set in the keyring.
  * ``keyring.errors.PasswordDeleteError``: Raised when the password can't be deleted in the keyring.

  ------------
  Get involved
  ------------

  Python keyring lib is an open community project and highly welcomes new
  contributors.

  * Repository: https://github.com/jaraco/keyring/
  * Bug Tracker: https://github.com/jaraco/keyring/issues/
  * Mailing list: http://groups.google.com/group/python-keyring

  Making Releases
  ===============

  This project makes use of automated releases via Travis-CI. The
  simple workflow is to tag a commit and push it to Github. If it
  passes tests on a late Python version, it will be automatically
  deployed to PyPI.

  Other things to consider when making a release:

   - first ensure that tests pass (preferably on Windows and Linux)
   - check that the changelog is current for the intended release

  Running Tests
  =============

  Tests are `continuously run <https://travis-ci.org/#!/jaraco/keyring>`_ using
  Travis-CI.

  To run the tests yourself, you'll want keyring installed to some environment
  in which it can be tested. Recommended technique is described below.

  Using tox
  ---------

  Keyring prefers use of `tox <https://pypi.org/project/tox>`_ to run tests.
  Simply install and invoke ``tox``.

  This technique is the one used by the Travis-CI script.

  ----------
  Background
  ----------

  The project was based on Tarek Ziade's idea in `this post`_. Kang Zhang
  initially carried it out as a `Google Summer of Code`_ project, and Tarek
  mentored Kang on this project.

  .. _this post: http://tarekziade.wordpress.com/2009/03/27/pycon-hallway-session-1-a-keyring-library-for-python/
  .. _Google Summer of Code: http://socghop.appspot.com/


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


pkgId: bd301cf32dce7d79c7df57453b5b74660326ec38a6aebe03b96d7060bb71d8f9
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: 625d97d9e5e742a99ad888ce0ac5f415
rpm_sourcerpm: rh-python36-keystoneauth1-3.18.0-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143877-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: 62e7b4da43e2db6e07e1c5e60332fb545c84cfe3b01582bdd651cbc4447af8b8
name: rh-python36-knack
arch: noarch
version: 0.3.3
epoch: 0
release: 1
summary: A Command-Line Interface framework
url: https://github.com/microsoft/knack
rpm_license: MIT
rpm_vendor: Microsoft Corporation <azpycli@microsoft.com>
rpm_group: Development/Libraries
rpm_buildhost: 220eb3676adb43a29aa6da017616ec19
rpm_sourcerpm: rh-python36-knack-0.3.3-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879050-rh-python36-knack/rh-python36-knack-0.3.3-1.noarch.rpm
checksum_type: sha256
description:
  Knack
  =====

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

  .. image:: https://img.shields.io/pypi/pyversions/knack.svg
      :target: https://pypi.python.org/pypi/knack

  .. image:: https://travis-ci.org/Microsoft/knack.svg?branch=master
      :target: https://travis-ci.org/Microsoft/knack


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


  ::

      _                     _
     | | ___ __   __ _  ___| | __
     | |/ / '_ \ / _` |/ __| |/ /
     |   <| | | | (_| | (__|   <
     |_|\_\_| |_|\__,_|\___|_|\_\


  **A Command-Line Interface framework**


  .. code-block:: bash

      pip install knack


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

  .. note:: The project is in `initial development phase <https://semver.org/#how-should-i-deal-with-revisions-in-the-0yz-initial-development-phase>`__ . We recommend pinning to at least a specific minor version when marking **knack** as a dependency in your project.

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


  Usage
  =====


  .. code-block:: python

      import sys
      from collections import OrderedDict
      from knack import CLI, CLICommandsLoader, ArgumentsContext

      def abc_list(myarg):
          import string
          return list(string.ascii_lowercase)

      class MyCommandsLoader(CLICommandsLoader):
          def load_command_table(self, args):
              with CommandGroup(__name__, self, 'abc', '__main__#{}') as g:
                  g.command('list', 'abc_list')
              return OrderedDict(self.command_table)

          def load_arguments(self, command):
              with ArgumentsContext(self, 'abc list') as ac:
                  ac.argument('myarg', type=int, default=100)
              super(MyCommandsLoader, self).load_arguments(command)

      mycli = CLI(cli_name='mycli', commands_loader_cls=MyCommandsLoader)
      exit_code = mycli.invoke(sys.argv[1:])
      sys.exit(exit_code)


  More samples and snippets available at `examples <examples>`__.


  Documentation
  =============

  Documentation is available at `docs <docs>`__.

  Developer Setup
  ===============

  In a virtual environment, install the `requirements.txt` file.

  .. code-block:: bash

      pip install -r requirements.txt
      pip install -e .

  Run Automation
  ==============

  This project supports running automation using `tox <https://tox.readthedocs.io/en/latest/>`__.

  .. code-block:: bash

      pip install tox
      tox


  Real-world uses
  ===============

  - `Azure CLI <https://github.com/Azure/azure-cli/>`__: The Azure CLI 2.0 is Azure's new command line experience for managing Azure resources.
  - `VSTS CLI <https://github.com/Microsoft/vsts-cli>`__: A command-line interface for Visual Studio Team Services (VSTS) and Team Foundation Server (TFS). With the VSTS CLI, you can manage and work with resources including pull requests, work items, builds, and more.
  - `Service Fabric CLI <https://github.com/Azure/service-fabric-cli>`__: A command-line interface for interacting with Azure Service Fabric clusters and their related entities.

  Do you use knack in your CLI as well? Open a pull request to include it here. We would love to have it in our list.


  Release History
  ===============

  See `GitHub Releases <https://github.com/Microsoft/knack/releases>`__.


  Contribute Code
  ===============

  This project has adopted the `Microsoft Open Source Code of Conduct <https://opensource.microsoft.com/codeofconduct/>`__.

  For more information see the `Code of Conduct FAQ <https://opensource.microsoft.com/codeofconduct/faq/>`__ or contact `opencode@microsoft.com <mailto:opencode@microsoft.com>`__ with any additional questions or comments.

  If you would like to become an active contributor to this project please
  follow the instructions provided in `Contribution License Agreement <https://cla.microsoft.com/>`__


  License
  =======

  Knack is licensed under `MIT <LICENSE>`__.


pkgId: 2fe6e3c22b26ae9823ec8803ff0ef1925d8d9abfece2c92a90736c72727b9574
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: 761738891d844e789d914bd710cb8e87
rpm_sourcerpm: rh-python36-kombu-4.6.7-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143806-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: f4a9b4dd4fc2a06268cd9d1f3a049acb2c672f277da8ebe08bccb3a27903123a
name: rh-python36-libselinux-python
arch: ppc64le
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: b4fbd98297a14854abe081060ed5e024
rpm_sourcerpm: rh-python36-libselinux-python-2.5-14.1.el7.src.rpm
location_href: 00885592-rh-python36-libselinux-python/rh-python36-libselinux-python-2.5-14.1.el7.ppc64le.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: e49f655eb87bdbad4199ffb464dc680ae61e3d5633c89196848dc727ad325bf6
name: rh-python36-libselinux-python-debuginfo
arch: ppc64le
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: b4fbd98297a14854abe081060ed5e024
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:
  00885592-rh-python36-libselinux-python/rh-python36-libselinux-python-debuginfo-2.5-14.1.el7.ppc64le.rpm


pkgId: 249e5f316874e89ecc46b8dcaefddfc84e8f7534624de31d5ed8057b3f9ecae3
name: rh-python36-lockfile
arch: noarch
version: 0.12.2
epoch: 0
release: 1
summary: Platform-independent file locking module
url: http://launchpad.net/pylockfile
rpm_license: UNKNOWN
rpm_vendor: OpenStack <openstack-dev@lists.openstack.org>
rpm_group: Development/Libraries
rpm_buildhost: 0c5feaddd78a4579b07c9e0cd651a25b
rpm_sourcerpm: rh-python36-lockfile-0.12.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879526-rh-python36-lockfile/rh-python36-lockfile-0.12.2-1.noarch.rpm
checksum_type: sha256
description:
  Note: This package is **deprecated**. It is highly preferred that instead of
  using this code base that instead `fasteners`_ or `oslo.concurrency`_ is
  used instead. For any questions or comments or further help needed
  please email `openstack-dev`_ and prefix your email subject
  with ``[oslo][pylockfile]`` (for a faster response).

  The lockfile package exports a LockFile class which provides a simple API for
  locking files.  Unlike the Windows msvcrt.locking function, the fcntl.lockf
  and flock functions, and the deprecated posixfile module, the API is
  identical across both Unix (including Linux and Mac) and Windows platforms.
  The lock mechanism relies on the atomic nature of the link (on Unix) and
  mkdir (on Windows) system calls.  An implementation based on SQLite is also
  provided, more as a demonstration of the possibilities it provides than as
  production-quality code.

  Note: In version 0.9 the API changed in two significant ways:

   * It changed from a module defining several classes to a package containing
     several modules, each defining a single class.

   * Where classes had been named SomethingFileLock before the last two words
     have been reversed, so that class is now SomethingLockFile.

  The previous module-level definitions of LinkFileLock, MkdirFileLock and
  SQLiteFileLock will be retained until the 1.0 release.

  To install:

      python setup.py install

  * Documentation: http://docs.openstack.org/developer/pylockfile
  * Source: http://git.openstack.org/cgit/openstack/pylockfile
  * Bugs: http://bugs.launchpad.net/pylockfile


pkgId: 0217cea3bd97293e4ff2d0fd86ce3db1fc0a30466232ca367f5fb6e8a7d258fb
name: rh-python36-lxml
arch: ppc64le
version: 4.4.2
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: 5057be99ea6544a3b70c01b575c250d7
rpm_sourcerpm: rh-python36-lxml-4.4.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143809-rh-python36-lxml/rh-python36-lxml-4.4.2-1.ppc64le.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: 770c36b13576a83d9c74fcdd068dfbe98350654d698e6318cfbe398f4655d317
name: rh-python36-lxml-debuginfo
arch: ppc64le
version: 4.4.2
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: 5057be99ea6544a3b70c01b575c250d7
rpm_sourcerpm: rh-python36-lxml-4.4.2-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 01143809-rh-python36-lxml/rh-python36-lxml-debuginfo-4.4.2-1.ppc64le.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: b5f0e32531eac1f208280adf739e1a187078632f8a57ea7d2b100951ebbfe82d
name: rh-python36-m2r
arch: noarch
version: 0.2.1
epoch: 0
release: 1
summary: Markdown and reStructuredText in a single file.
url: https://github.com/miyakogi/m2r
rpm_license: MIT
rpm_vendor: Hiroyuki Takagi <miyako.dev@gmail.com>
rpm_group: Development/Libraries
rpm_buildhost: 8425cee09e9f4993ae57aba7edd35d11
rpm_sourcerpm: rh-python36-m2r-0.2.1-1.src.rpm
rpm_packager: Martin Juhl <m@rtinjuhl.dk>
location_href: 00879054-rh-python36-m2r/rh-python36-m2r-0.2.1-1.noarch.rpm
checksum_type: sha256
description:
  M2R
  ===

  [![PyPI](https://img.shields.io/pypi/v/m2r.svg)](https://pypi.python.org/pypi/m2r)
  [![PyPI version](https://img.shields.io/pypi/pyversions/m2r.svg)](https://pypi.python.org/pypi/m2r)
  [![Documentation](https://img.shields.io/badge/docs-latest-brightgreen.svg)](https://miyakogi.github.io/m2r)
  [![Build Status](https://travis-ci.org/miyakogi/m2r.svg?branch=master)](https://travis-ci.org/miyakogi/m2r)
  [![codecov](https://codecov.io/gh/miyakogi/m2r/branch/master/graph/badge.svg)](https://codecov.io/gh/miyakogi/m2r)

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

  M2R converts a markdown file including reStructuredText (rst) markups to a valid
  rst format.



  I wanted to write sphinx document in markdown, since it's widely used now and
  easy to write code blocks and lists. However, converters using pandoc or
  recommonmark do not support many rst markups and sphinx extensions. For
  example, rst's reference link like ``see `ref`_`` (this is very convenient in
  long document in which same link appears multiple times) will be converted to
  a code block in HTML like `see <code>ref</code>_`, which is not expected.



  * Basic markdown and some extensions (see below)
      * inline/block-level raw html
      * fenced-code block
      * tables
      * footnotes (``[^1]``)
  * Inline- and Block-level rst markups
      * single- and multi-line directives (`.. directive::`)
      * inline-roles (``:code:`print(1)` ...``)
      * ref-link (``see `ref`_``)
      * footnotes (``[#fn]_``)
      * math extension inspired by [recommonmark](https://recommonmark.readthedocs.io/en/latest/index.html)
  * Sphinx extension
      * add markdown support for sphinx
      * ``mdinclude`` directive to include markdown from md or rst files
      * option to parse relative links into ref and doc directives (``m2r_parse_relative_links``)
  * Pure python implementation
      * pandoc is not required



  Python 2.7 or Python 3.4+ is required.

  ```
  pip install m2r
  ```

  Or,

  ```
  python3 -m pip install m2r
  ```





  `m2r` command converts markdown file to rst format.

  ```
  m2r your_document.md [your_document2.md ...]
  ```

  Then you will find `your_document.rst` in the same directory.



  Import `m2r.convert` function and call it with markdown text.
  Then it will return converted text.

  ```python
  from m2r import convert
  rst = convert('# Title\n\nSentence.')
  print(rst)




  ```

  Or, use `parse_from_file` function to load markdown file and obtain converted
  text.

  ```python
  from m2r import parse_from_file
  output = parse_from_file('markdown_file.md')
  ```

  This is an example of setup.py to write README in markdown, and publish it to
  PyPI as rst format.

  ```python
  readme_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'README.md')
  try:
      from m2r import parse_from_file
      readme = parse_from_file(readme_file)
  except ImportError:
      
      with open(readme_file) as f:
          readme = f.read()
  setup(
      ...,
      long_description=readme,
      ...,
  )
  ```



  In your conf.py, add the following lines.

  ```python
  extensions = [
      ...,
      'm2r',
  ]


  source_suffix = ['.rst', '.md']
  ```

  Write index.md and run `make html`.

  When `m2r` extension is enabled on sphinx and `.md` file is loaded, m2r
  converts to rst and pass to sphinx, not making new `.rst` file.



  Like `.. include:: file` directive, `.. mdinclude:: file` directive inserts
  markdown file at the line.

  Note: do not use `.. include:: file` directive to include markdown file even if
  in the markdown file, please use `.. mdinclude:: file` instead.



  * In the rst's directives, markdown is not available. Please write in rst.
  * Column alignment of tables is not supported. (rst does not support this feature)
  * Heading with overline-and-underline is not supported.
    * Heading with underline is OK
  * Rst heading marks are currently hard-coded and unchangeable.
    * H1: `=`, H2: `-`, H3: `^`, H4: `~`, H5: `"`, H6: `#`

  If you find any bug or unexpected behaviour, please report it to
  [Issues](https://github.com/miyakogi/m2r/issues).



  See [example document](https://miyakogi.github.io/m2r/example.html) and [its
  source code](https://github.com/miyakogi/m2r/blob/master/docs/example.md).

  I'm using m2r for writing user guide of [WDOM](https://github.com/miyakogi/wdom).
  So you can see it as another example. Its [HTML is
  here](http://wdom-py.readthedocs.io/en/latest/guide/index.html), and [its
  source code is here](https://github.com/miyakogi/wdom/tree/dev/docs/guide).



  Demo editor of m2r is available.
  If you are interested in m2r, please try it.

  [https://github.com/miyakogi/m2rdemo](https://github.com/miyakogi/m2rdemo)



  m2r is written as an extension of
  [mistune](http://mistune.readthedocs.io/en/latest/), which is highly extensible
  pure-python markdown parser.
  Without the mistune, I couldn't write this. Thank you!



  [MIT](https://github.com/miyakogi/m2r/blob/master/LICENSE)


