{ "info": { "author": "Solly Ross", "author_email": "sross@redhat.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: ISC License (ISCL)", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "========\nShouldBe\n========\n\n---------------------------------------------\nPython Assertion Helpers Inspired by Shouldly\n---------------------------------------------\n\nRequirements\n============\n\n- forbiddenfruit\n- a version of python with which forbidden fruit will work\n (must implement the CTypes/CPython Python API)\n- Python 2.7 or 3.3\n (it may work with other versions, such as other 3.x versions,\n but it has not been tested with these versions)\n\nAssertions\n==========\n\nSee `ASSERTIONS.rst `_\n\nExample\n=======\n\n::\n\n >>> import should_be.all\n >>> class Cheese(object):\n ... crackers = 3\n ...\n >>> swiss = Cheese()\n >>> swiss.crackers.should_be(4)\n AssertionError: swiss.crackers should have been 4, but was 3\n\n\n.. note::\n\n Because of the way the Python REPL shows stack traces, if the 'should_be'\n assertion is typed in a line on the REPL, '(unknown)' will show instead\n of 'swiss.crackers'. This is not an issue when the 'should_be' statement\n is in a file instead.\n\nInstallation\n============\n\nThe easy way\n\n.. code-block:: bash\n\n $ sudo pip install https://github.com/DirectXMan12/should_be.git#egg=ShouldBe\n\nThe slightly-less-easy way\n\n.. code-block:: bash\n\n $ git clone https://github.com/DirectXMan12/should_be.git\n $ cd should_be\n $ ./setup.py build\n $ sudo ./setup.py install\n\nExtending\n=========\n\n.. role:: python(code)\n :language: python\n\nWriting your own assertions is fairly easy. There are two core parts of\nShouldBe: :python:`BaseMixin` and `should_follow`.\n\nAll assertions should be placed in classes that inherit from :python:`BaseMixin`.\n:python:`BaseMixin` provides the basic utilities for extending built-in objects\nwith your assertions.\n\nThe class which holds your assertions should have a class variable called\n:python:`target_class`. This is the class on which your assertions will be run.\nBy default, this is set to :python:`object`. If you wish to have your assertions\nrun on :python:`object`, there are a few additional considerations to make (see\nwarning below).\n\nThen, assertions should be defined as instance methods. Each method should call\n:python:`self.should_follow` one or more times. Think of `should_follow` as `assertTrue`\non steroids. It has the following signature:\n:python:`should_follow(self, assertion, msg=None, **kwargs)`. Obviously, assertion is\nan expression which, when :python:`False`, causes `should_follow` to raise an `AssertionError`.\nSo far, pretty normal. :python:`msg` is where things get interesting. `msg` should be\na new-style Python format string which contains only named substitutions. By\ndefault, :python:`should_follow` will pass the `txt` and `self` keys to the `format` method,\nin addition to any keyword arguments passed to :python:`should_follow`. `self` is, obviously,\nthe current object. :python:`txt` is the code that represents the current object. For instance,\nif we wrote :python:`(3).should_be(4)`, `txt` would be '(3)'. If we wrote\n:python:`cheese.variety.should_be('cheddar')`, `txt` would be 'cheese.variety'.\n\nOnce all of your assertions are written, you can simply write\n:python:`MyAssertionMixin.mix()` to load your assertions. A `setuptools`\nhook is on the way for autoloading custom assertion mixins\nwith :python:`import should_be.all`.\n\n.. warning::\n\n When you extend object, you need to also create the proper mixins for\n :python:`NoneType`, since `None` doesn't have instance methods per-se (since\n :python:`self` gets set to `None`, the Python interpreter complains). Thankfully,\n this is fairly easy. Simply create a class which inherits from :python:`NoneTypeMixin`,\n and set the class variable :python:`source_class` to the name of your `object` assertions\n class. You can then simply run :python:`MyNoneTypeMixin.mix()`, and your methods will\n be automatically retrieved and converted from your :python:`object` mixin class.\n\n.. note::\n\n Assertions for ABCs (such as Sequence) will be automatically mixed in to 'registered'\n classes that do not inherit methods from the ABCs normally (such as list, etc) when\n the :python:`mix()` method is called (this will also check for classes that are registered\n to subclasses of the ABCs).", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/directxman12/should_be", "keywords": "testing,assertions", "license": "LICENSE.txt", "maintainer": "", "maintainer_email": "", "name": "shouldbe", "package_url": "https://pypi.org/project/shouldbe/", "platform": "", "project_url": "https://pypi.org/project/shouldbe/", "project_urls": { "Homepage": "https://github.com/directxman12/should_be" }, "release_url": "https://pypi.org/project/shouldbe/0.1.2/", "requires_dist": null, "requires_python": "", "summary": "Python Assertion Helpers inspired by Shouldly", "version": "0.1.2" }, "last_serial": 4908889, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "fae18f564fc875d7263b4e0543d0f46a", "sha256": "e404d2ca08ed44c049b08cf9c5c1a3736719d49884f80e265b72f7b06f87ec1e" }, "downloads": -1, "filename": "shouldbe-0.1.0.tar.gz", "has_sig": false, "md5_digest": "fae18f564fc875d7263b4e0543d0f46a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15018, "upload_time": "2015-01-05T22:09:07", "url": "https://files.pythonhosted.org/packages/dd/b9/fa2d71a2278c3d6456dfe838509688533f1e506076080228e122d7a4fb15/shouldbe-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "b426c7e51fd85597071ba1f3c70c7791", "sha256": "c3fd395529a546199d216fb3df8b3a4c80355dcfed46788ad9ab5070a184730d" }, "downloads": -1, "filename": "shouldbe-0.1.1.tar.gz", "has_sig": false, "md5_digest": "b426c7e51fd85597071ba1f3c70c7791", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13625, "upload_time": "2019-03-06T06:40:05", "url": "https://files.pythonhosted.org/packages/89/bf/8a52bdb657f4aa160325e594ea1ffbe2e84eda7f50f13db35a9ff21bd7b6/shouldbe-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "5807c5ab1c5dac83f49a0ada243d9e74", "sha256": "f28a330ef849835bd242bb851eb7cbad8e1a7d8b26b3b79c27b485e3badceb9b" }, "downloads": -1, "filename": "shouldbe-0.1.2.tar.gz", "has_sig": false, "md5_digest": "5807c5ab1c5dac83f49a0ada243d9e74", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13622, "upload_time": "2019-03-07T07:49:37", "url": "https://files.pythonhosted.org/packages/f1/7d/79c9e9bf95ae86b73dee2bc4888d35a7b86f3d6b0acbcc22e3154861e84e/shouldbe-0.1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5807c5ab1c5dac83f49a0ada243d9e74", "sha256": "f28a330ef849835bd242bb851eb7cbad8e1a7d8b26b3b79c27b485e3badceb9b" }, "downloads": -1, "filename": "shouldbe-0.1.2.tar.gz", "has_sig": false, "md5_digest": "5807c5ab1c5dac83f49a0ada243d9e74", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13622, "upload_time": "2019-03-07T07:49:37", "url": "https://files.pythonhosted.org/packages/f1/7d/79c9e9bf95ae86b73dee2bc4888d35a7b86f3d6b0acbcc22e3154861e84e/shouldbe-0.1.2.tar.gz" } ] }