Metadata-Version: 1.1
Name: py-flags
Version: 1.0.0
Summary: Type-safe (bit)flags for python 3
Home-page: https://github.com/pasztorpisti/py-flags
Author: István Pásztor
Author-email: pasztorpisti@gmail.com
License: MIT
Description: ========
        py-flags
        ========
        
        Type-safe (bit)flags
        """"""""""""""""""""
        
        
        .. image:: https://img.shields.io/travis/pasztorpisti/py-flags.svg?style=flat
            :target: https://travis-ci.org/pasztorpisti/py-flags
            :alt: build
        
        .. image:: https://img.shields.io/codacy/0c56231fea3a49b48bc39d0803ec3c21/master.svg?style=flat
            :target: https://www.codacy.com/app/pasztorpisti/py-flags
            :alt: code quality
        
        .. image:: https://landscape.io/github/pasztorpisti/py-flags/master/landscape.svg?style=flat
            :target: https://landscape.io/github/pasztorpisti/py-flags/master
            :alt: code health
        
        .. image:: https://img.shields.io/coveralls/pasztorpisti/py-flags/master.svg?style=flat
            :target: https://coveralls.io/r/pasztorpisti/py-flags?branch=master
            :alt: coverage
        
        .. image:: https://img.shields.io/pypi/v/py-flags.svg?style=flat
            :target: https://pypi.python.org/pypi/py-flags
            :alt: pypi
        
        .. image:: https://img.shields.io/github/tag/pasztorpisti/py-flags.svg?style=flat
            :target: https://github.com/pasztorpisti/py-flags
            :alt: github
        
        .. image:: https://img.shields.io/github/license/pasztorpisti/py-flags.svg?style=flat
            :target: https://github.com/pasztorpisti/py-flags/blob/master/LICENSE.txt
            :alt: license: MIT
        
        
        .. contents::
        
        
        Quick Intro
        ===========
        
        With this module you can define type-safe (bit)flags. The style of the flag definition is very similar to the enum
        definitions you can create using the standard ``enum`` module of python 3.
        
        
        Defining flags with the ``class`` syntax:
        
        .. code-block:: python
        
            >>> from flags import Flags
        
            >>> class TextStyle(Flags):
            >>>     bold = 1            # value = 1 << 0
            >>>     italic = 2          # value = 1 << 1
            >>>     underline = 4       # value = 1 << 2
        
        
        In most cases you just want to use the flags as a set (of ``bool`` variables) and the actual flag values aren't
        important. To avoid manually setting unique flag values you can use auto assignment. To auto-assign a unique flag value
        use an empty iterable (for example empty tuple or list) as the value of the flag. Auto-assignment picks the first
        unused least significant bit for each auto-assignable flag in top-to-bottom order.
        
        .. code-block:: python
        
            >>> class TextStyle(Flags):
            >>>     bold = ()           # value = 1 << 0
            >>>     italic = ()         # value = 1 << 1
            >>>     underline = ()      # value = 1 << 2
        
        
        As a shortcut you can call a flags class to create a subclass of it. This pattern has also been stolen from the
        standard ``enum`` module. The following flags definition is equivalent to the previous definition that uses the
        ``class`` syntax:
        
        
        .. code-block:: python
        
            >>> TextStyle = Flags('TextStyle', 'bold italic underline')
        
        
        Flags have human readable string representations and ``repr`` with more info:
        
        .. code-block:: python
        
            >>> print(TextStyle.bold)
            TextStyle.bold
            >>> print(repr(TextStyle.bold))
            <TextStyle.bold bits=0x0001 data=None>
        
        The type of a flag is the flags class it belongs to:
        
        .. code-block:: python
        
            >>> type(TextStyle.bold)
            <class '__main__.TextStyle'>
            >>> isinstance(TextStyle.bold, TextStyle)
            True
        
        
        You can combine flags with bool operators. The result is also an instance of the flags class with the previously
        described properties.
        
        .. code-block:: python
        
            >>> result = TextStyle.bold | TextStyle.italic
            >>>
            >>> print(result)
            TextStyle(bold|italic)
            >>> print(repr(result))
            <TextStyle(bold|italic) bits=0x0003>
        
        
        Operators work in a type-safe way: you can combine only flags of the same type. Trying to combine them with instances
        of other types results in error:
        
        .. code-block:: python
        
            >> result = TextStyle.bold | 1
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            TypeError: unsupported operand type(s) for |: 'TextStyle' and 'int'
            >>>
            >>> class OtherFlags(Flags):
            ...     flag0 = ()
            ...
            >>> result = TextStyle.bold | OtherFlags.flag0
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
            TypeError: unsupported operand type(s) for |: 'TextStyle' and 'OtherFlags'
        
        
        Flags and their combinations (basically the instances of the flags class) are immutable and hashable so they can be
        used as set members and dictionary keys:
        
        .. code-block:: python
        
            >>> font_files = {}
            >>> font_files[TextStyle.bold] = 'bold.ttf'
            >>> font_files[TextStyle.italic] = 'italic.ttf'
            >>> font_files == {TextStyle.bold: 'bold.ttf', TextStyle.italic: 'italic.ttf'}
            True
        
        
        The flags you define automatically have two "virtual" flags: ``no_flags`` and ``all_flags``. ``no_flags`` is basically
        the zero flag and ``all_flags`` is the combination of all flags you've defined:
        
        .. code-block:: python
        
            >>> TextStyle.no_flags
            <TextStyle() bits=0x0000>
            >>> TextStyle.all_flags
            <TextStyle(bold|italic|underline) bits=0x0007>
        
        
        Testing whether specific flags are set:
        
        .. code-block:: python
        
            >>> result = TextStyle.bold | TextStyle.italic
            >>> bool(result & TextStyle.bold)       # 1. oldschool bit twiddling
            True
            >>> TextStyle.bold in result            # 2. in operator
            True
            >>> result.bold                         # 3. attribute-style access
            True
        
        
        From the above testing methods the attribute-style access can only check the presence of a single flag. With the
        ``&`` and ``in`` operators you can check the presence of multiple flags at the same time:
        
        .. code-block:: python
        
            >>> bool((TextStyle.bold | TextStyle.italic) & TextStyle.all_flags)
            True
            >>> (TextStyle.bold | TextStyle.italic) in TextStyle.all_flags
            True
        
        
        If for some reason you need the actual integer value of the flags then you can cast them to ``int``:
        
        .. code-block:: python
        
            >>> int(TextStyle.bold)
            1
        
        
        You can convert the ``int()`` and ``str()`` representations of flags back into flags instances:
        
        .. code-block:: python
        
            >>> TextStyle(2)
            <TextStyle.italic bits=0x0002 data=None>
            >>> TextStyle('TextStyle.bold')
            <TextStyle.bold bits=0x0001 data=None>
        
        
        Installation
        ============
        
        .. code-block:: sh
        
            pip install py-flags
        
        Alternatively you can download the distribution from the following places:
        
        - https://pypi.python.org/pypi/py-flags#downloads
        - https://github.com/pasztorpisti/py-flags/releases
        
        Introduction
        ============
        
        We can use integers as an effective storage for a bunch of ``bool`` variables packed together. If we name the
        individual bits of the integer and we aren't interested in their individual position/value then we can also treat
        our integer as:
        
        - A set: a named ``bool`` variable - a bit from the integer - is part of the set if it's value is ``True``/``1``.
        - An object that has (of course named) ``bool`` attributes.
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        As usual this has its own pros and cons:
        
        **Pros:**
        
        - You can store several ``bool`` values in a single object:
        
            - It's easy to pass it as a single function parameter and function signatures don't have to be refactored
              in case of adding/removing ``bool`` variables that are part of the flag.
        
        - Performing ``bool`` operations on flags can result in simpler and easier to read code than doing the same with
          individual ``bool`` variables that make up the integer.
        
        **Cons:**
        
        treat flags as a bunch of ``bool`` variables packed together into an integer.
        If we give each bit a name in the integer and the actual integer value of each bit doesn't matter then we can also
        treat this as a **set** of items/flags.
        
        
        
        
        
Keywords: flags bit flag set bitfield bool arithmetic
Platform: UNKNOWN
Classifier: License :: OSI Approved :: MIT License
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
