prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Fix payable registry cache using old data
  ### Describe the bug
  Payments are a mess. For example, if you pay for an event registration, delete the payment (through the admin or api), creating a new TPay payment through the api fails with 409 Conflict, there is still a payment in the registration model, but not in the payments api. Furthermore, paying with a different payment type works, but those payments can then not be removed. Also see #1806. I suspect there are many more related problems.
  
  ### How to reproduce
  Play around with payable things, deleting and recreating them, or deleting and recreating payments.
  
  ### Expected behaviour
  When a payable is not paid and should be payable with TPay, paying does not fail. Deleting a payment makes the payable not-paid as it was before creating the payment. Deleting or changing a payable is either impossible, or also deletes a payment that belongs to it.
  
  ### Additional context
  I think it would be a good idea to combine this with #1000. Some test-driven development would make sense for payments, and I think the expected behaviour should be well-testable. Of course the problems may not be entirely within the payments app, but also in the payables defined by other apps.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `website/payments/payables.py`
  Content:
  ```
  1 from functools import lru_cache
  2 
  3 from django.db.models import Model
  4 
  5 _registry = {}
  6 
  7 
  8 class NotRegistered(Exception):
  9     pass
  10 
  11 
  12 class Payable:
  13     def __init__(self, model: Model):
  14         self.model = model
  15 
  16     @property
  17     def pk(self):
  18         return self.model.pk
  19 
  20     @property
  21     def payment(self):
  22         return self.model.payment
  23 
  24     @payment.setter
  25     def payment(self, payment):
  26         self.model.payment = payment
  27 
  28     @property
  29     def payment_amount(self):
  30         raise NotImplementedError
  31 
  32     @property
  33     def payment_topic(self):
  34         raise NotImplementedError
  35 
  36     @property
  37     def payment_notes(self):
  38         raise NotImplementedError
  39 
  40     @property
  41     def payment_payer(self):
  42         raise NotImplementedError
  43 
  44     @property
  45     def tpay_allowed(self):
  46         return True
  47 
  48     def can_manage_payment(self, member):
  49         raise NotImplementedError
  50 
  51 
  52 class Payables:
  53     _registry = {}
  54 
  55     @lru_cache(maxsize=None)
  56     def _get_key(self, model):
  57         return f"{model._meta.app_label}_{model._meta.model_name}"
  58 
  59     @lru_cache(maxsize=None)
  60     def get_payable(self, model: Model) -> Payable:
  61         if self._get_key(model) not in self._registry:
  62             raise NotRegistered(f"No Payable registered for {self._get_key(model)}")
  63         return self._registry[self._get_key(model)](model)
  64 
  65     def register(self, model: Model, payable_class: Payable):
  66         self._registry[self._get_key(model)] = payable_class
  67 
  68 
  69 payables = Payables()
  70
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/website/payments/payables.py b/website/payments/payables.py
  --- a/website/payments/payables.py
  +++ b/website/payments/payables.py
  @@ -56,7 +56,6 @@
       def _get_key(self, model):
           return f"{model._meta.app_label}_{model._meta.model_name}"
   
  -    @lru_cache(maxsize=None)
       def get_payable(self, model: Model) -> Payable:
           if self._get_key(model) not in self._registry:
               raise NotRegistered(f"No Payable registered for {self._get_key(model)}")
  
verification_info: {"golden_diff": "diff --git a/website/payments/payables.py b/website/payments/payables.py\n--- a/website/payments/payables.py\n+++ b/website/payments/payables.py\n@@ -56,7 +56,6 @@\n     def _get_key(self, model):\n         return f\"{model._meta.app_label}_{model._meta.model_name}\"\n \n-    @lru_cache(maxsize=None)\n     def get_payable(self, model: Model) -> Payable:\n         if self._get_key(model) not in self._registry:\n             raise NotRegistered(f\"No Payable registered for {self._get_key(model)}\")\n", "issue": "Fix payable registry cache using old data\n### Describe the bug\r\nPayments are a mess. For example, if you pay for an event registration, delete the payment (through the admin or api), creating a new TPay payment through the api fails with 409 Conflict, there is still a payment in the registration model, but not in the payments api. Furthermore, paying with a different payment type works, but those payments can then not be removed. Also see #1806. I suspect there are many more related problems.\r\n\r\n### How to reproduce\r\nPlay around with payable things, deleting and recreating them, or deleting and recreating payments.\r\n\r\n### Expected behaviour\r\nWhen a payable is not paid and should be payable with TPay, paying does not fail. Deleting a payment makes the payable not-paid as it was before creating the payment. Deleting or changing a payable is either impossible, or also deletes a payment that belongs to it.\r\n\r\n### Additional context\r\nI think it would be a good idea to combine this with #1000. Some test-driven development would make sense for payments, and I think the expected behaviour should be well-testable. Of course the problems may not be entirely within the payments app, but also in the payables defined by other apps.\r\n\n", "before_files": [{"content": "from functools import lru_cache\n\nfrom django.db.models import Model\n\n_registry = {}\n\n\nclass NotRegistered(Exception):\n    pass\n\n\nclass Payable:\n    def __init__(self, model: Model):\n        self.model = model\n\n    @property\n    def pk(self):\n        return self.model.pk\n\n    @property\n    def payment(self):\n        return self.model.payment\n\n    @payment.setter\n    def payment(self, payment):\n        self.model.payment = payment\n\n    @property\n    def payment_amount(self):\n        raise NotImplementedError\n\n    @property\n    def payment_topic(self):\n        raise NotImplementedError\n\n    @property\n    def payment_notes(self):\n        raise NotImplementedError\n\n    @property\n    def payment_payer(self):\n        raise NotImplementedError\n\n    @property\n    def tpay_allowed(self):\n        return True\n\n    def can_manage_payment(self, member):\n        raise NotImplementedError\n\n\nclass Payables:\n    _registry = {}\n\n    @lru_cache(maxsize=None)\n    def _get_key(self, model):\n        return f\"{model._meta.app_label}_{model._meta.model_name}\"\n\n    @lru_cache(maxsize=None)\n    def get_payable(self, model: Model) -> Payable:\n        if self._get_key(model) not in self._registry:\n            raise NotRegistered(f\"No Payable registered for {self._get_key(model)}\")\n        return self._registry[self._get_key(model)](model)\n\n    def register(self, model: Model, payable_class: Payable):\n        self._registry[self._get_key(model)] = payable_class\n\n\npayables = Payables()\n", "path": "website/payments/payables.py"}], "after_files": [{"content": "from functools import lru_cache\n\nfrom django.db.models import Model\n\n_registry = {}\n\n\nclass NotRegistered(Exception):\n    pass\n\n\nclass Payable:\n    def __init__(self, model: Model):\n        self.model = model\n\n    @property\n    def pk(self):\n        return self.model.pk\n\n    @property\n    def payment(self):\n        return self.model.payment\n\n    @payment.setter\n    def payment(self, payment):\n        self.model.payment = payment\n\n    @property\n    def payment_amount(self):\n        raise NotImplementedError\n\n    @property\n    def payment_topic(self):\n        raise NotImplementedError\n\n    @property\n    def payment_notes(self):\n        raise NotImplementedError\n\n    @property\n    def payment_payer(self):\n        raise NotImplementedError\n\n    @property\n    def tpay_allowed(self):\n        return True\n\n    def can_manage_payment(self, member):\n        raise NotImplementedError\n\n\nclass Payables:\n    _registry = {}\n\n    @lru_cache(maxsize=None)\n    def _get_key(self, model):\n        return f\"{model._meta.app_label}_{model._meta.model_name}\"\n\n    def get_payable(self, model: Model) -> Payable:\n        if self._get_key(model) not in self._registry:\n            raise NotRegistered(f\"No Payable registered for {self._get_key(model)}\")\n        return self._registry[self._get_key(model)](model)\n\n    def register(self, model: Model, payable_class: Payable):\n        self._registry[self._get_key(model)] = payable_class\n\n\npayables = Payables()\n", "path": "website/payments/payables.py"}]}