# -*- coding: utf-8 -*-
from setuptools import setup

modules = \
['sentinel']
extras_require = \
{'varname': ['varname>=0.1']}

setup_kwargs = {
    'name': 'sentinel',
    'version': '0.3.0',
    'description': 'Create sentinel objects, akin to None, NotImplemented, Ellipsis',
    'long_description': '*************************************************\nsentinel — create sentinel and singleton objects\n*************************************************\n\n|Tests| |PyPI version|\n\n.. |Tests| image:: https://github.com/eddieantonio/sentinel/workflows/Test%20and%20Lint/badge.svg\n   :target: https://github.com/eddieantonio/sentinel/actions?query=workflow%3A%22Test+and+Lint%22\n.. |PyPI version| image:: https://img.shields.io/pypi/v/sentinel\n   :target: https://pypi.org/project/sentinel/\n\nCreates simple sentinel objects.\n\n\nInstall\n=======\n\nBasic features::\n\n   pip install sentinel\n\nwith extra magic features powered by python-varname_::\n\n   pip install \'sentinel[varname]\'\n\n\nWhat is a sentinel?\n===================\n\nSentinels_ are singleton_ objects that typically represent some\nterminating (end) condition or have a special, symbolic meaning. Python\'s built-in\n``None`` is a sentinel. Python also has other sentinels like ``NotImplemented`` and\n``Ellipsis``.\n\nIf you want to create your own sentinels, use this library! Make your calls to\n``dict.get()`` more meaningful! You can replace the ``object()`` idiom with a sentinel:\n\n.. code-block:: python\n\n   d = {"a": 1, "b": None}\n\n   # Before sentinel:\n   missing = object()\n   if d.get("c", missing) is missing:\n       ... # do some stuff\n\n   # After sentinel:\n   Missing = sentinel.create()\n   if d.get("c", Missing) is Missing:\n       ... # do some stuff\n\n\nFeatures\n--------\n\n - sentinels are unique\n - sentinels are singletons — the **only** instance of their own anonymous class\n - sentinels can be used with ``is`` comparisons\n - sentinels can be used with ``pickle``\n - sentinels can be used with ``copy.deepcopy``\n - you can **add** arbitrary attributes and methods to sentinels\n - sentinels have a nice, self-documenting ``__repr__``!\n\nUsage\n=====\n\nCreate a sentinel:\n\n>>> import sentinel\n>>> MySentinel = sentinel.create("MySentinel")\n>>> Sentinel\nSentinel\n\nIf you have python-varname_ installed, or installed this module using\n``pip install \'sentinel[varname]\'``, ``sentinel.create()`` can infer the name\nfrom the assignment expression:\n\n.. code-block:: python\n\n   import sentinel\n\n   MySentinel = sentinel.create()\n\n   print(MySentinel)  # prints `MySentinel`\n\n\nExample\n-------\n\nSentinels are useful when other objects such as ``None``, ``False``,\n``0``, ``-1``, are valid values within some data structure. For example, setting\ndefault values when all other values are valid with:\n``dict.setdefault()``:\n\n.. code-block:: python\n\n   d = {"stdout": None, "stdin": 0, "EOF": -1}\n\n   MissingEntry = sentinel.create()\n\n   [d.setdefault(key, MissingEntry) for key in ("stdin", "stdout", "stderr")]\n   [0, None, MissingEntry]\n\nAlternatively, using ``dict.get()`` when fetching values:\n\n>>> d = {"stdout": None, "stdin": 0, "EOF": -1}\n>>> d.get("stdout", MissingEntry)\nNone\n>>> d.get("stdin", MissingEntry)\n0\n>>> d.get("stderr", MissingEntry)\nMissingEntry\n\nSince a new sentinel can never occur in the original dictionary, you can tell which\nentries are missing or unset in a dictionary in a self-documenting way:\n\n.. code-block:: python\n\n   Unset = sentinel.create()\n   if d.get("stdin", Unset) is Unset:\n       stdin = 0  # some reasonable default\n\n\nAdding extra methods and class attributes\n-----------------------------------------\n\nSentinels may also inherit from base classes, or implement extra methods.\n\nConsider a binary search tree with two kinds of nodes: interior nodes\n(``Node``) which contain some payload and leaves (``Leaf``), which simply\nterminate traversal.\n\nTo create singleton leaf which implements a ``search`` method and an\n``is_leaf`` property, you may provide any extra class attributes in the\n``cls_dict`` keyword argument. The following is a full example of both\nthe singleton ``Leaf`` and its ``Node`` counterpart:\n\n.. code-block:: python\n\n    def _search_leaf(self, key):\n        raise KeyError(key)\n\n    Leaf = sentinel.create(\'Leaf\', cls_dict={\n        \'search\': _search_leaf,\n        \'is_leaf\': property(lambda self: True)\n    })\n\n    class Node(object):\n        def __init__(self, key, payload, left=Leaf, right=Leaf):\n            self.left = left\n            self.right = right\n            self.key = key\n            self.payload = payload\n\n        def search(self, key):\n            if key < self.key:\n                return self.left.search(key)\n            elif key > self.key:\n                return self.right.search(key)\n            else:\n                return self.payload\n\n        is_leaf = property(lambda: false)\n\nExample usage:\n\n>>> tree = Node(2, \'bar\', Node(1, \'foo\'), Node(3, \'baz\'))\n>>> tree.search(1)\n\'foo\'\n>>> tree.search(4)\nTraceback (most recent call last):\n    ...\nKeyError: 2\n\n\nContributing\n============\n\nThis project uses Poetry_. To contribute to the codebase, make sure to `install poetry`_,\nWith Poetry installed, clone then repo, then within the repo directory, install the developer dependencies::\n\n    $ poetry install --extras varname\n\nNext, I recommend you do all development tasks within the ``poetry shell``::\n\n    $ poetry shell\n    (sentinel-nUnrocCf-py3.9) $ black .\n    (sentinel-nUnrocCf-py3.9) $ pytest\n\n.. _Sentinels: http://en.wikipedia.org/wiki/Sentinel_nodes\n.. _singleton: http://en.wikipedia.org/wiki/Singleton_pattern\n.. _Poetry: https://python-poetry.org/\n.. _install poetry: https://python-poetry.org/docs/#installation\n.. _python-varname: https://github.com/pwwang/python-varname\n',
    'author': 'Eddie Antonio Santos',
    'author_email': 'easantos@ualberta.ca',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/eddieantonio/sentinel',
    'py_modules': modules,
    'extras_require': extras_require,
    'python_requires': '>=3.6,<4.0',
}


setup(**setup_kwargs)
