{ "info": { "author": "Tim Diels", "author_email": "limyreth@users.sourceforge.net", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License (GPL)", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.0", "Programming Language :: Python :: 3.1", "Programming Language :: Python :: 3.2", "Topic :: Software Development :: Libraries", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "Pytilities is a python3 utility library.\n\nLinks\n=====\n\n- `Pytilities homepage`_\n- `Documentation`_\n\n\nFeatures\n========\n\n- Aspect oriented programming: \n\n - Create Aspects to bundle advice\n - Apply advice to any attribute of an instance or all instances of a class.\n Can even be applied to attributes that don't exist on the instance (i.e.\n create it). Can also be applied to any attribute of an object.\n\n- Event dispatching: Observer/Subject like event dispatching with wrappers\n for hiding events on dispatchers and combining dispatchers\n- Function overloading\n- Basic geometry: Vector, Rectangle classes\n- Various: cross platform infinity number, ...\n\n\n.. _Pytilities homepage: http://pytilities.sourceforge.net/\n.. _Documentation: http://pytilities.sourceforge.net/doc/1.2.0/\n\n\nChangelog\n=========\n\n1.2.0\n-----\n\npytilities.aop\n''''''''''''''\nAdvising is more KISS now. You map your advice in a plain dictionary, instead \nof using _advise. '*' advice is now gone, instead you can use a special \ndictionary like object: pytilities.dictionary.FunctionMap. It allows for '*' \nadvice and more.\n\n:Changed:\n - `Aspect`:\n\n - Added:\n\n - `_advice_mappings`: Mapping of (access, attribute_name) to advice. Note\n that '*' is not a valid attribute_name, use `FunctionMap` instead of\n the old '*' advice. If you use `FunctionMap` you should set\n `_undefined_keys` to True.\n - `_undefined_keys`: set to True if _advice_mappings provides infinite\n mappings\n\n - Removed:\n\n - `_advise`: use `_advice_mappings` instead\n\n:Fixed:\n - fixed a special case of invalid call advising, see \n pytilities.test.aop.calladvisespecialcase\n\n\npytilities.aop.aspects\n''''''''''''''''''''''\n:Fixed:\n - `View`: the aspect did not correctly enable its aspect upon calling \n callables through the view\n\n\npytilities.delegation\n'''''''''''''''''''''\nDelegation is more KISS now. The complex Profile class was removed in favor\nof plain dictionaries (and those of pytilities.dictionary). `in_profile` is\nreplaced by the more flexible and KISS `mapped`.\n\n:Added:\n - `mapped`: adds an attribute to a mapping in a format that can be used\n as argument to DelegationAspect. You could also use it as a base for the\n _advice_mappings of your Aspect, ...\n - `mapped_class`: required on a class for `mapped` to work\n\n:Changed:\n - `DelegationAspect`:\n\n - no longer expects a Profile parameter, instead it expects a mapping of \n (access, source_attribute_name) to target_attribute_name; where \n access is 'get', 'set', or 'delete', as opposed to 'r', 'w', or\n 'd'.\n\n:Removed:\n - `profile_carrier`: use `mapped_class` instead\n - `in_profile`: use `mapped` instead\n - `Profile`: replaced by plain dictionaries (This is more flexible and KISS \n than the vague Profile interface)\n\n\npytilities.dictionary (new)\n'''''''''''''''''''''''''''\n:Added:\n - `FunctionMap`: A Mapping that uses a function to generate its values\n\n\npytilities.event\n''''''''''''''''\n:Changed:\n - `DispatcherSwitch`: now has its 'delegation profile' stored in\n public_mapping\n - `Dispatcher`: now has its 'delegation profile' stored in\n public_mapping and default_mapping\n\n\npytilities.tests\n''''''''''''''''\n:Changed:\n - `is_private`: now only returns True for names matching __name or\n _SomeClass_name.\n\n:Fixed:\n - `is_special`: returned False on special attributes\n\n\n1.1.0\n-----\n\npytilities.aop\n''''''''''''''\nMade aop more KISS so it's easier to understand, use (and maintain):\n\n- Distinction between class and instance advice may now be forgotten, there's\n only advice. Classes act as wildcards now, e.g. aspect.apply(Class) means\n apply to all instances of Class and Class itself.\n- You can now apply an aspect to all instances from a class and then exclude an\n instance from that advice by unapplying it afterwards.\n\nImproved test coverage (less bugs now).\n\n:Added:\n - `advisor.get_applied_aspects(obj)`\n - `AOPException`\n - `yield suppress_aspect`: context manager that prevents the current aspect\n from having its advice executed till the end of the context\n - `yield advised_attribute`: replaces (yield name, yield advised).\n - `yield advised_instance`: returns the instance to which the aspect was applied \n (or the class in case the advised is a static/class method)\n\n:Changed:\n - `Aspect`:\n\n - `_advise`: You can no longer advise a member more than once. This \n includes trying to advise '*' and some regular member at the same time.\n (this makes Aspect more KISS, you can workaround this limitation \n using multiple aspects)\n - `is_enabled`: now returns False for objects to which it is not applied\n - `apply`: now applies the aspect to all instances of cls and cls \n itself when supplied a class\n - `unapply`: now unapplies the aspect on all instances of cls and cls\n itself when supplied a class\n - `unapply_all`: now unapplies all aspects on all instances of cls \n and cls itself when supplied a class\n - `is_applied`: returns True, if given object is in\n advisor.get_applied_aspects(obj)\n\n:Removed:\n - `yield name`: Removed in favor of the clearer `yield advised_attribute`\n - `yield advised`: Removed in favor of the clearer `yield advised_attribute`\n - `yield obj`: Removed in favor of the clearer `yield advised_instance`\n - Support for advising modules: It has become too hard too maintain this\n feature while there are decent workarounds for this lack:\n\n - Put your functions in a class with staticmethods or classmethods\n - Or use the singleton pattern.\n\n And then apply the aspect to that class.\n\n:Fixes:\n - `advisor.unapply_all`: forgot to implement it\n - `yield advised` returned the wrong callable on call access\n - When trying to get an unexisting attribute after having had advice \n applied and unapplied to it, the object would no longer throw \n AttributeError on get access\n - `Aspect.enable` and `Aspect.disable` had no effect\n\n\npytilities.aop.aspects\n''''''''''''''''''''''\n\n:Added:\n - `ImmutableAttributeException`\n\n:Changed:\n - `ImmutableAspect`: as required by the fix (see below):\n - it can now only be applied on objects with AOPMeta as metaclass\n - it now raises ImmutableAttributeException on attempts to mutate\n\n:Fixes:\n - `create_view`: did not enable its aspect on access\n - `ImmutableAspect`: it only worked for detecting change on setters, it now \n detects every change. \n\npytilities.descriptors\n''''''''''''''''''''''\nAdded and refactored tests\n\n:Added:\n - `DereferencedBoundDescriptor`: like BoundDescriptor but takes 2 descriptors\n as args that are dereferenced(/read/getted) on each call.\n\n:Changed:\n - `BoundDescriptor`:\n \n - `special_dereference` parameter was removed\n - instance arg will no longer be dereferenced when a descriptor arg is\n passed\n\n If you need any of the two above, use DereferencedBoundDescriptor.\n (splitting the class in two like this would make it more intuitive to use)\n\n\n1.0.1\n-----\nIncluded project.py in release so that unit tests can be run\n\n\n1.0.0\n-----\nThe library moved to python3, older python versions are no longer supported.\nThere a lot of changes, breaking quite a bit of the previous interface. All\nchanges are listed below.\n\n\npytilities \n''''''''''\n\n:Added:\n - get_annotations: gets annotations of an object, allows to add new ones,\n ...\n - get_attr_name, get_attr_value, has_attr_name, has_attr_value: gets an\n attribute, bypassing regular lookup (no descriptor.__get__, ..., does\n support inheritance though)\n\n:Removed: \n - AttributeCollection, AttributeCollectionBase: use aop instead (see User\n Guide)\n\n:Changed:\n - mangle: \n\n - You can now pass an instance as well.\n - Small fix involving class names that start with a '_'\n\npytilities.aop \n''''''''''''''\n\nThis package brings aspect oriented language features to python (in a handy\nformat). You can apply advice on classes and instances, using aspects that can\nbe applied and unapplied, enabled, disabled, ...\n\n:Added:\n - advisor: singleton that aspects use to give advice (you shouldn't use\n this directly, derive from Aspect and use its methods instead)\n - proceed, return_close, return\\_, arguments, advised, obj, name yields for\n advice functions\n - Aspect: base class to write your own aspects with (you are not required\n to use this, but it is greatly recommended)\n - AOPMeta: classes that are given * advice require to have AOPMeta as\n metaclass, other advised classes may benefit from this metaclass as it\n reduces memory usage\n\npytilities.delegation \n'''''''''''''''''''''\n\n:Added:\n - DelegationAspect: delegate attributes from a source instance/cls to a\n target. Only supports direct mappings (mappings with the same source and\n target attributes).\n - in_profile, profile_carrier: used to more easily place some profiles on a\n class\n\n:Changed:\n - Profile\n\n:Removed:\n - Delegator, DelegatorFactory: use delegate or any of the other\n possibilities listed in the User Guide instead\n - delegator_factory: use profile_carrier instead.\n - delegated: use in_profile instead.\n - delegate: use DelegationAspect instead. You may want to read about AOP in\n the user guide first\n\npytilities.descriptors (new) \n''''''''''''''''''''''''''''\n\n:Added:\n - AttributeDescriptor: turns a regular attribute into a descriptor\n - DereferencedDescriptor: returns inner_desc.get.get, sets\n inner_desc.get.set, ...\n - BoundDescriptor: binds an instance to a descriptor, much like bound\n methods\n - RestrictedDescriptor: strip of the get, set or del of a descriptor\n\npytilities.event \n''''''''''''''''\n\n:Removed:\n - dispatcher, dispatcherswitch (decorators): normally you'd send events\n from an aspect as it's a crosscutting concern, so these no longer have to\n be supported. Use a custom Aspect + DelegationAspect instead.\n\npytilities.geometry \n'''''''''''''''''''\n\n:Added:\n - DiscreteVector, DiscreteRectangle: A Vector/Rectangle with a discrete\n coordinate space. All aspects and views for Vector/Rectangle work on\n these as well.\n - verbose_rectangle_aspect, verbose_vector_aspect: Aspects to make a\n Rectangle/Vector send out (change) events.\n - ImmutableRectangle, ImmutableVector: immutable views of a\n Rectangle/Vector\n - immutable_rectangle_aspect, immutable_vector_aspect: makes a\n Rectangle/Vector immutable\n\n:Changed:\n - Vector, Rectangle: Due to a change in int division mechanisms in python3,\n these classes will always operate with a continuous coordinate space. I.e\n if your vector has coords (3, 1), then when divided by 2 they become\n (1.5, 0.5) and not (1, 0) as they used to be in previous versions. Use\n DiscreteVector and DiscreteRectangle instead, to get similar behaviour\n back.\n - Vector, DiscreteVector: have an extra overload for assign that accepts\n (x,y) as args\n\n:Removed:\n - BoundVector: use Vector directly instead (use its bound properties\n overload)\n - VerboseVector: make a Vector and do verbose_vector_aspect.apply(v)\n instead. This works for DiscreteVectors as well.\n - VerboseRectangle: make a Rectangle and do\n verbose_rectangle_aspect.apply(v) instead. This works for DiscreteVectors\n as well.\n\npytilities.overloading \n''''''''''''''''''''''\n\n:Changed:\n - overloaded: its returned function now has a process_args method as well\n - Parameter: its ctor was incorrectly overloaded (ironically). This has\n been fixed, its overloads changed slightly because of this.\n\npytilities.infinity (new) \n'''''''''''''''''''''''''\n\nProvides a cross-platform alternative to float('inf').\n\n:Added:\n - infinity, negative_infinity, nan\n - is_infinity\n\npytilities.tests \n''''''''''''''''\n\n:Added:\n - is_public, is_protected, is_private, is_special: attribute name checks\n\n\n0.1.4\n-----\n\n- Mangle, mangling and event.dispatcher: fixed a slight name clash\n- Overhauled testing, it is now easier to use\n- Removed inheritance feature of DelegatorFactory, it was too vague\n- Removed __init_delegation_profiles, there are other ways to achieve the same\n thing\n- Changed the DelegatorFactory interface so that it is hopefully more intuitive\n to use\n- Added all set operators to delegation.Profile\n- Added more tests and fixed some docstrings\n- RestrictedDispatcher: Made allow and disallow mutually exclusive. It made no\n sense to specify both\n\n\n0.1.3\n-----\n\n- Added html reference documentation\n\n\n0.1.2\n-----\n\n- Added runtests.py, which allows running unit tests\n- Added the types package (forgot this in last release)\n\n\n0.1.1\n-----\n\n- Fixed: the last release wouldn't parse\n\n\n0.1.0\n-----\n\n- Initial release: delegation tools, events, overloading, ...", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pytilities.sourceforge.net", "keywords": "utility,library,aop,aspect,oriented,event,overloading", "license": "UNKNOWN", "maintainer": null, "maintainer_email": null, "name": "pytilities", "package_url": "https://pypi.org/project/pytilities/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/pytilities/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://pytilities.sourceforge.net" }, "release_url": "https://pypi.org/project/pytilities/1.2.0/", "requires_dist": null, "requires_python": null, "summary": "A collection of python coding utilities", "version": "1.2.0" }, "last_serial": 798165, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "46fad5a7f118459e19620dc867cc3193", "sha256": "b0dfe95f66fb1e655df3e21bd3918687e9488bc3187e8cd425cc58b6954f1505" }, "downloads": -1, "filename": "pytilities-0.1.0.tar.gz", "has_sig": false, "md5_digest": "46fad5a7f118459e19620dc867cc3193", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41588, "upload_time": "2010-07-15T16:32:11", "url": "https://files.pythonhosted.org/packages/a4/4c/e1ae38bbb2d15cdefee99553d31167a389e55b8bd18ef8722feee723ed18/pytilities-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "61f9dc4e7fe56bba8cf46c72e6e9c10f", "sha256": "b267980fa3495e79a30a3fdfb818a5ea37e3b77b7a1408769ebabf693185d9f5" }, "downloads": -1, "filename": "pytilities-0.1.1.tar.gz", "has_sig": false, "md5_digest": "61f9dc4e7fe56bba8cf46c72e6e9c10f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 40964, "upload_time": "2010-07-16T13:28:57", "url": "https://files.pythonhosted.org/packages/9a/8e/d383865c8edb99bddb6c5bcb05af65bbca8352008879bcd1c7c485e85f56/pytilities-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "fc3bb5627bfad729d6caeeda21e15ff6", "sha256": "e1231097ab09650b32bcf4e1d14813d0f7925cc9a5ee4c83a366472fc44280cb" }, "downloads": -1, "filename": "pytilities-0.1.2.tar.gz", "has_sig": false, "md5_digest": "fc3bb5627bfad729d6caeeda21e15ff6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 42340, "upload_time": "2010-07-16T14:02:25", "url": "https://files.pythonhosted.org/packages/62/dd/98240dfbc12a135233fd13d8cec4a5184cb97848adab25daaed41c9e60e8/pytilities-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "a667d077156899e09e57a2aa88fb9d7b", "sha256": "be9804f53945a51e54bf0d0121a1d643aa8b01479868d84c2f4a74bd6d69ebde" }, "downloads": -1, "filename": "pytilities-0.1.3.tar.gz", "has_sig": false, "md5_digest": "a667d077156899e09e57a2aa88fb9d7b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 366049, "upload_time": "2010-07-19T12:03:49", "url": "https://files.pythonhosted.org/packages/dd/e7/f21d143a38a3f5ad6ce28fd4f60e878e972248bacfa1e66fd68f994c11f9/pytilities-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "73d9e9116a8d913002c6536ae37d2c2e", "sha256": "7d7fe79d537193239652e1d7792ef7f04d87211bc83b9dc564442dcb9a3d6cc2" }, "downloads": -1, "filename": "pytilities-0.1.4.tar.gz", "has_sig": false, "md5_digest": "73d9e9116a8d913002c6536ae37d2c2e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 472459, "upload_time": "2010-07-22T13:13:20", "url": "https://files.pythonhosted.org/packages/aa/6d/0260ec2af3118ad5191df3f70aee1c3b55bdaa813f01ac7a2af710d666d6/pytilities-0.1.4.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "78658be58215e5ed3d29f834a1a3e134", "sha256": "d098bf33f9b530410a93e89e44629e1a79d796ee9121b624ce178e3d05e90ae1" }, "downloads": -1, "filename": "pytilities-1.0.0.tar.gz", "has_sig": false, "md5_digest": "78658be58215e5ed3d29f834a1a3e134", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 584391, "upload_time": "2010-12-25T13:03:30", "url": "https://files.pythonhosted.org/packages/20/ec/7f8135266e8637451b540f463897331f0fbf2ed952b74fcf29a3c8749be6/pytilities-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "9ff3262002267287119185322d74d858", "sha256": "6fd1a5eb58a2051a6f9fc142272e691edad852e38963fbf4b54221ebae54f071" }, "downloads": -1, "filename": "pytilities-1.0.1.tar.gz", "has_sig": false, "md5_digest": "9ff3262002267287119185322d74d858", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 587562, "upload_time": "2010-12-25T13:35:35", "url": "https://files.pythonhosted.org/packages/32/0f/230aab2bed8a965008d1edd433e18620a5e25091665cac2b8dd6bba10e9f/pytilities-1.0.1.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "0dd0b7240b875a0b8adee220c3b5e4fc", "sha256": "1f3a6f44193a91d5fc5dd08b6d1b551e4bd363b63caa42f6d0a5ef8762328ea7" }, "downloads": -1, "filename": "pytilities-1.1.0.tar.gz", "has_sig": false, "md5_digest": "0dd0b7240b875a0b8adee220c3b5e4fc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 483270, "upload_time": "2011-03-19T20:41:28", "url": "https://files.pythonhosted.org/packages/59/0b/b2c87d97d69f29864d180623a8f3eea903d9070f71439dd09b902cab43aa/pytilities-1.1.0.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "24e412e76c247c8ed49b3aa364394cd5", "sha256": "dc45759a43055fc8de7e00fe1eabf1f0b60e6e9a4c702066ef34225e3db5e2b3" }, "downloads": -1, "filename": "pytilities-1.2.0.tar.gz", "has_sig": false, "md5_digest": "24e412e76c247c8ed49b3aa364394cd5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 490100, "upload_time": "2011-03-27T17:47:24", "url": "https://files.pythonhosted.org/packages/ee/38/7d5bae93685bd9faf8f4beea14a6de338d80b2292cf0159d7d4a5930a71d/pytilities-1.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "24e412e76c247c8ed49b3aa364394cd5", "sha256": "dc45759a43055fc8de7e00fe1eabf1f0b60e6e9a4c702066ef34225e3db5e2b3" }, "downloads": -1, "filename": "pytilities-1.2.0.tar.gz", "has_sig": false, "md5_digest": "24e412e76c247c8ed49b3aa364394cd5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 490100, "upload_time": "2011-03-27T17:47:24", "url": "https://files.pythonhosted.org/packages/ee/38/7d5bae93685bd9faf8f4beea14a6de338d80b2292cf0159d7d4a5930a71d/pytilities-1.2.0.tar.gz" } ] }