{"id":17269084,"url":"https://github.com/bennylope/garland","last_synced_at":"2025-03-26T11:43:24.371Z","repository":{"id":25834792,"uuid":"29274208","full_name":"bennylope/garland","owner":"bennylope","description":"Garland is simple, repeatable decorator mocking.","archived":false,"fork":false,"pushed_at":"2022-12-26T19:44:00.000Z","size":25,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T08:13:03.492Z","etag":null,"topics":["decorators","mock","python","testing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bennylope.png","metadata":{"files":{"readme":"README.rst","changelog":"HISTORY.rst","contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-15T01:11:06.000Z","updated_at":"2018-07-09T18:28:34.000Z","dependencies_parsed_at":"2023-01-14T03:31:11.610Z","dependency_job_id":null,"html_url":"https://github.com/bennylope/garland","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennylope%2Fgarland","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennylope%2Fgarland/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennylope%2Fgarland/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bennylope%2Fgarland/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bennylope","download_url":"https://codeload.github.com/bennylope/garland/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245649731,"owners_count":20650097,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decorators","mock","python","testing"],"created_at":"2024-10-15T08:15:18.282Z","updated_at":"2025-03-26T11:43:24.341Z","avatar_url":"https://github.com/bennylope.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"=================================\ngarland: Python decorator mocking\n=================================\n\n.. image:: https://secure.travis-ci.org/bennylope/garland.svg?branch=master\n    :alt: Build Status\n    :target: http://travis-ci.org/bennylope/garland\n\n.. image:: https://img.shields.io/pypi/v/garland.svg\n    :alt: Current PyPI release\n    :target: https://crate.io/packages/garland\n\n.. image:: https://img.shields.io/pypi/dm/garland.svg\n    :alt: Download count\n    :target: https://crate.io/packages/garland\n\nGarland is simple, repeatable decorator mocking.\n\nWhy?\n====\n\nDecorators are applied at the time the decorated function is first imported, which\nmakes `mocking them a bit more challenging \u003chttp://alexmarandon.com/articles/python_mock_gotchas/#patching-decorators\u003e`_.\n\nI want to be able to be simply patch decorators - typically making them just pass-throughs to\nignore their functionality - without modifying the underlying codebase. And I don't want\nto worry about whether a module has already been loaded and is now unpatchable, or it needs\nto be patched for every test... and I don't want to write the patching/loading/reloading\ncode for every test.\n\nUsage\n=====\n\nProvided you have a function that you want to test, like so:\n\n.. code:: python\n\n    @my_decorator\n    def something_cool(*args, **kwargs):\n        ...\n        return some_var\n\nWith your `my_decoroator` decorator defined in another module, you can mock\n`my_decorator` so that you can test just the end decorated function.\n\nIn your test, apply the `tinsel` decorator function to the test method where\nyou want the decorator mocked.\n\n.. code:: python\n\n    @garland.tinsel('utils.decorators.my_decorator', 'very_cool.module')\n    def test_something_cool(self):\n        self.assertEqual(very_cool.module.something_cool(), \"undecorated value\")\n\nNow `test_something` can test the return values from `something_cool` without\nthe decorator potentially returning a different value, or providing a different\nfunction interface.\n\nThe `tinsel` decorator takes two arguments:\n\n1. A dotted path to the decorator function you want to mock\n2. A dotted path to the module in which your function - the one you're testing -\n   is declared. If you're not importing the module like this in your tests then\n   this will do you little good (see limits, below).\n\nLimits\n======\n\n1. You need to import modules, not named functions, to work with garland.\n2. For now this is only tested with decorator functions and function decorators\n3. The mock turns your decorator into a pass-through, assuming that this is the\n   way you want to mock it.\n4. Only Python 3.4 and Python 2.7 are supported at this time.\n\n\nLicense\n=======\n\nCopyright Ben Lopatin. BSD licensed (see `LICENSE`).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbennylope%2Fgarland","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbennylope%2Fgarland","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbennylope%2Fgarland/lists"}