We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Memory backend sometimes show empty permissions
If you do multiple requests on memory backend, the empty permissions cycle between showing and not showing. The same does not happen with postgres.

```json
gsurita-30820:kinto gsurita$ echo '{"permissions": {"read": []}}' | http put localhost:8888/v1/buckets/b1 -a a:a

{
    "data": {
        "id": "b1",
        "last_modified": 1485553456205
    },
    "permissions": {
        "write": [
            "basicauth:80866b4d0726f35eda20b90bc479a38727c99c68d7c88a87f3b860726a79daeb"
        ]
    }
}

gsurita-30820:kinto gsurita$ echo '{"permissions": {"read": []}}' | http put localhost:8888/v1/buckets/b1 -a a:a

{
    "data": {
        "id": "b1",
        "last_modified": 1485553470501
    },
    "permissions": {
        "collection:create": [],
        "group:create": [],
        "read": [],
        "write": [
            "basicauth:80866b4d0726f35eda20b90bc479a38727c99c68d7c88a87f3b860726a79daeb"
        ]
    }
}

gsurita-30820:kinto gsurita$ echo '{"permissions": {"read": []}}' | http put localhost:8888/v1/buckets/b1 -a a:a

{
    "data": {
        "id": "b1",
        "last_modified": 1485553471419
    },
    "permissions": {
        "write": [
            "basicauth:80866b4d0726f35eda20b90bc479a38727c99c68d7c88a87f3b860726a79daeb"
        ]
    }
}

gsurita-30820:kinto gsurita$ echo '{"permissions": {"read": []}}' | http put localhost:8888/v1/buckets/b1 -a a:a

{
    "data": {
        "id": "b1",
        "last_modified": 1485553472203
    },
    "permissions": {
        "collection:create": [],
        "group:create": [],
        "read": [],
        "write": [
            "basicauth:80866b4d0726f35eda20b90bc479a38727c99c68d7c88a87f3b860726a79daeb"
        ]
    }
}


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kinto/core/permission/memory.py`
Content:
```
1 import re
2 
3 from kinto.core.decorators import synchronized
4 from kinto.core.permission import PermissionBase
5 
6 
7 class Permission(PermissionBase):
8     """Permission backend implementation in local process memory.
9 
10     Enable in configuration::
11 
12         kinto.permission_backend = kinto.core.permission.memory
13 
14     :noindex:
15     """
16 
17     def __init__(self, *args, **kwargs):
18         super().__init__(*args, **kwargs)
19         self.flush()
20 
21     def initialize_schema(self, dry_run=False):
22         # Nothing to do.
23         pass
24 
25     def flush(self):
26         self._store = {}
27 
28     @synchronized
29     def add_user_principal(self, user_id, principal):
30         user_key = 'user:{}'.format(user_id)
31         user_principals = self._store.get(user_key, set())
32         user_principals.add(principal)
33         self._store[user_key] = user_principals
34 
35     @synchronized
36     def remove_user_principal(self, user_id, principal):
37         user_key = 'user:{}'.format(user_id)
38         user_principals = self._store.get(user_key, set())
39         try:
40             user_principals.remove(principal)
41         except KeyError:
42             pass
43         if len(user_principals) == 0:
44             if user_key in self._store:
45                 del self._store[user_key]
46         else:
47             self._store[user_key] = user_principals
48 
49     @synchronized
50     def remove_principal(self, principal):
51         for user_principals in self._store.values():
52             try:
53                 user_principals.remove(principal)
54             except KeyError:
55                 pass
56 
57     @synchronized
58     def get_user_principals(self, user_id):
59         # Fetch the groups the user is in.
60         user_key = 'user:{}'.format(user_id)
61         members = self._store.get(user_key, set())
62         # Fetch the groups system.Authenticated is in.
63         group_authenticated = self._store.get('user:system.Authenticated', set())
64         return members | group_authenticated
65 
66     @synchronized
67     def add_principal_to_ace(self, object_id, permission, principal):
68         permission_key = 'permission:{}:{}'.format(object_id, permission)
69         object_permission_principals = self._store.get(permission_key, set())
70         object_permission_principals.add(principal)
71         self._store[permission_key] = object_permission_principals
72 
73     @synchronized
74     def remove_principal_from_ace(self, object_id, permission, principal):
75         permission_key = 'permission:{}:{}'.format(object_id, permission)
76         object_permission_principals = self._store.get(permission_key, set())
77         try:
78             object_permission_principals.remove(principal)
79         except KeyError:
80             pass
81         if len(object_permission_principals) == 0:
82             if permission_key in self._store:
83                 del self._store[permission_key]
84         else:
85             self._store[permission_key] = object_permission_principals
86 
87     @synchronized
88     def get_object_permission_principals(self, object_id, permission):
89         permission_key = 'permission:{}:{}'.format(object_id, permission)
90         members = self._store.get(permission_key, set())
91         return members
92 
93     @synchronized
94     def get_accessible_objects(self, principals, bound_permissions=None, with_children=True):
95         principals = set(principals)
96         candidates = []
97         if bound_permissions is None:
98             for key, value in self._store.items():
99                 _, object_id, permission = key.split(':', 2)
100                 candidates.append((object_id, permission, value))
101         else:
102             for pattern, perm in bound_permissions:
103                 id_match = '.*' if with_children else '[^/]+'
104                 regexp = re.compile('^{}$'.format(pattern.replace('*', id_match)))
105                 for key, value in self._store.items():
106                     if key.endswith(perm):
107                         object_id = key.split(':')[1]
108                         if regexp.match(object_id):
109                             candidates.append((object_id, perm, value))
110 
111         perms_by_object_id = {}
112         for (object_id, perm, value) in candidates:
113             if len(principals & value) > 0:
114                 perms_by_object_id.setdefault(object_id, set()).add(perm)
115         return perms_by_object_id
116 
117     @synchronized
118     def get_authorized_principals(self, bound_permissions):
119         principals = set()
120         for obj_id, perm in bound_permissions:
121             principals |= self.get_object_permission_principals(obj_id, perm)
122         return principals
123 
124     @synchronized
125     def get_objects_permissions(self, objects_ids, permissions=None):
126         result = []
127         for object_id in objects_ids:
128             if permissions is None:
129                 aces = [k for k in self._store.keys()
130                         if k.startswith('permission:{}:'.format(object_id))]
131             else:
132                 aces = ['permission:{}:{}'.format(object_id, permission)
133                         for permission in permissions]
134             perms = {}
135             for ace in aces:
136                 # Should work with 'permission:/url/id:record:create'.
137                 permission = ace.split(':', 2)[2]
138                 perms[permission] = set(self._store[ace])
139             result.append(perms)
140         return result
141 
142     @synchronized
143     def replace_object_permissions(self, object_id, permissions):
144         for permission, principals in permissions.items():
145             permission_key = 'permission:{}:{}'.format(object_id, permission)
146             if permission_key in self._store and len(principals) == 0:
147                 del self._store[permission_key]
148             else:
149                 self._store[permission_key] = set(principals)
150         return permissions
151 
152     @synchronized
153     def delete_object_permissions(self, *object_id_list):
154         to_delete = []
155         for key in self._store.keys():
156             object_id = key.split(':')[1]
157             for pattern in object_id_list:
158                 regexp = re.compile('^{}$'.format(pattern.replace('*', '.*')))
159                 if regexp.match(object_id):
160                     to_delete.append(key)
161         for k in to_delete:
162             del self._store[k]
163 
164 
165 def load_from_config(config):
166     return Permission()
167
```
--- 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()

```

diff --git a/kinto/core/permission/memory.py b/kinto/core/permission/memory.py
--- a/kinto/core/permission/memory.py
+++ b/kinto/core/permission/memory.py
@@ -145,7 +145,7 @@
             permission_key = 'permission:{}:{}'.format(object_id, permission)
             if permission_key in self._store and len(principals) == 0:
                 del self._store[permission_key]
-            else:
+            elif principals:
                 self._store[permission_key] = set(principals)
         return permissions

{"golden_diff": "diff --git a/kinto/core/permission/memory.py b/kinto/core/permission/memory.py\n--- a/kinto/core/permission/memory.py\n+++ b/kinto/core/permission/memory.py\n@@ -145,7 +145,7 @@\n             permission_key = 'permission:{}:{}'.format(object_id, permission)\n             if permission_key in self._store and len(principals) == 0:\n                 del self._store[permission_key]\n-            else:\n+            elif principals:\n                 self._store[permission_key] = set(principals)\n         return permissions\n", "issue": "Memory backend sometimes show empty permissions\nIf you do multiple requests on memory backend, the empty permissions cycle between showing and not showing. The same does not happen with postgres.\r\n\r\n```json\r\ngsurita-30820:kinto gsurita$ echo '{\"permissions\": {\"read\": []}}' | http put localhost:8888/v1/buckets/b1 -a a:a\r\n\r\n{\r\n    \"data\": {\r\n        \"id\": \"b1\",\r\n        \"last_modified\": 1485553456205\r\n    },\r\n    \"permissions\": {\r\n        \"write\": [\r\n            \"basicauth:80866b4d0726f35eda20b90bc479a38727c99c68d7c88a87f3b860726a79daeb\"\r\n        ]\r\n    }\r\n}\r\n\r\ngsurita-30820:kinto gsurita$ echo '{\"permissions\": {\"read\": []}}' | http put localhost:8888/v1/buckets/b1 -a a:a\r\n\r\n{\r\n    \"data\": {\r\n        \"id\": \"b1\",\r\n        \"last_modified\": 1485553470501\r\n    },\r\n    \"permissions\": {\r\n        \"collection:create\": [],\r\n        \"group:create\": [],\r\n        \"read\": [],\r\n        \"write\": [\r\n            \"basicauth:80866b4d0726f35eda20b90bc479a38727c99c68d7c88a87f3b860726a79daeb\"\r\n        ]\r\n    }\r\n}\r\n\r\ngsurita-30820:kinto gsurita$ echo '{\"permissions\": {\"read\": []}}' | http put localhost:8888/v1/buckets/b1 -a a:a\r\n\r\n{\r\n    \"data\": {\r\n        \"id\": \"b1\",\r\n        \"last_modified\": 1485553471419\r\n    },\r\n    \"permissions\": {\r\n        \"write\": [\r\n            \"basicauth:80866b4d0726f35eda20b90bc479a38727c99c68d7c88a87f3b860726a79daeb\"\r\n        ]\r\n    }\r\n}\r\n\r\ngsurita-30820:kinto gsurita$ echo '{\"permissions\": {\"read\": []}}' | http put localhost:8888/v1/buckets/b1 -a a:a\r\n\r\n{\r\n    \"data\": {\r\n        \"id\": \"b1\",\r\n        \"last_modified\": 1485553472203\r\n    },\r\n    \"permissions\": {\r\n        \"collection:create\": [],\r\n        \"group:create\": [],\r\n        \"read\": [],\r\n        \"write\": [\r\n            \"basicauth:80866b4d0726f35eda20b90bc479a38727c99c68d7c88a87f3b860726a79daeb\"\r\n        ]\r\n    }\r\n}\r\n\n", "before_files": [{"content": "import re\n\nfrom kinto.core.decorators import synchronized\nfrom kinto.core.permission import PermissionBase\n\n\nclass Permission(PermissionBase):\n    \"\"\"Permission backend implementation in local process memory.\n\n    Enable in configuration::\n\n        kinto.permission_backend = kinto.core.permission.memory\n\n    :noindex:\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.flush()\n\n    def initialize_schema(self, dry_run=False):\n        # Nothing to do.\n        pass\n\n    def flush(self):\n        self._store = {}\n\n    @synchronized\n    def add_user_principal(self, user_id, principal):\n        user_key = 'user:{}'.format(user_id)\n        user_principals = self._store.get(user_key, set())\n        user_principals.add(principal)\n        self._store[user_key] = user_principals\n\n    @synchronized\n    def remove_user_principal(self, user_id, principal):\n        user_key = 'user:{}'.format(user_id)\n        user_principals = self._store.get(user_key, set())\n        try:\n            user_principals.remove(principal)\n        except KeyError:\n            pass\n        if len(user_principals) == 0:\n            if user_key in self._store:\n                del self._store[user_key]\n        else:\n            self._store[user_key] = user_principals\n\n    @synchronized\n    def remove_principal(self, principal):\n        for user_principals in self._store.values():\n            try:\n                user_principals.remove(principal)\n            except KeyError:\n                pass\n\n    @synchronized\n    def get_user_principals(self, user_id):\n        # Fetch the groups the user is in.\n        user_key = 'user:{}'.format(user_id)\n        members = self._store.get(user_key, set())\n        # Fetch the groups system.Authenticated is in.\n        group_authenticated = self._store.get('user:system.Authenticated', set())\n        return members | group_authenticated\n\n    @synchronized\n    def add_principal_to_ace(self, object_id, permission, principal):\n        permission_key = 'permission:{}:{}'.format(object_id, permission)\n        object_permission_principals = self._store.get(permission_key, set())\n        object_permission_principals.add(principal)\n        self._store[permission_key] = object_permission_principals\n\n    @synchronized\n    def remove_principal_from_ace(self, object_id, permission, principal):\n        permission_key = 'permission:{}:{}'.format(object_id, permission)\n        object_permission_principals = self._store.get(permission_key, set())\n        try:\n            object_permission_principals.remove(principal)\n        except KeyError:\n            pass\n        if len(object_permission_principals) == 0:\n            if permission_key in self._store:\n                del self._store[permission_key]\n        else:\n            self._store[permission_key] = object_permission_principals\n\n    @synchronized\n    def get_object_permission_principals(self, object_id, permission):\n        permission_key = 'permission:{}:{}'.format(object_id, permission)\n        members = self._store.get(permission_key, set())\n        return members\n\n    @synchronized\n    def get_accessible_objects(self, principals, bound_permissions=None, with_children=True):\n        principals = set(principals)\n        candidates = []\n        if bound_permissions is None:\n            for key, value in self._store.items():\n                _, object_id, permission = key.split(':', 2)\n                candidates.append((object_id, permission, value))\n        else:\n            for pattern, perm in bound_permissions:\n                id_match = '.*' if with_children else '[^/]+'\n                regexp = re.compile('^{}$'.format(pattern.replace('*', id_match)))\n                for key, value in self._store.items():\n                    if key.endswith(perm):\n                        object_id = key.split(':')[1]\n                        if regexp.match(object_id):\n                            candidates.append((object_id, perm, value))\n\n        perms_by_object_id = {}\n        for (object_id, perm, value) in candidates:\n            if len(principals & value) > 0:\n                perms_by_object_id.setdefault(object_id, set()).add(perm)\n        return perms_by_object_id\n\n    @synchronized\n    def get_authorized_principals(self, bound_permissions):\n        principals = set()\n        for obj_id, perm in bound_permissions:\n            principals |= self.get_object_permission_principals(obj_id, perm)\n        return principals\n\n    @synchronized\n    def get_objects_permissions(self, objects_ids, permissions=None):\n        result = []\n        for object_id in objects_ids:\n            if permissions is None:\n                aces = [k for k in self._store.keys()\n                        if k.startswith('permission:{}:'.format(object_id))]\n            else:\n                aces = ['permission:{}:{}'.format(object_id, permission)\n                        for permission in permissions]\n            perms = {}\n            for ace in aces:\n                # Should work with 'permission:/url/id:record:create'.\n                permission = ace.split(':', 2)[2]\n                perms[permission] = set(self._store[ace])\n            result.append(perms)\n        return result\n\n    @synchronized\n    def replace_object_permissions(self, object_id, permissions):\n        for permission, principals in permissions.items():\n            permission_key = 'permission:{}:{}'.format(object_id, permission)\n            if permission_key in self._store and len(principals) == 0:\n                del self._store[permission_key]\n            else:\n                self._store[permission_key] = set(principals)\n        return permissions\n\n    @synchronized\n    def delete_object_permissions(self, *object_id_list):\n        to_delete = []\n        for key in self._store.keys():\n            object_id = key.split(':')[1]\n            for pattern in object_id_list:\n                regexp = re.compile('^{}$'.format(pattern.replace('*', '.*')))\n                if regexp.match(object_id):\n                    to_delete.append(key)\n        for k in to_delete:\n            del self._store[k]\n\n\ndef load_from_config(config):\n    return Permission()\n", "path": "kinto/core/permission/memory.py"}], "after_files": [{"content": "import re\n\nfrom kinto.core.decorators import synchronized\nfrom kinto.core.permission import PermissionBase\n\n\nclass Permission(PermissionBase):\n    \"\"\"Permission backend implementation in local process memory.\n\n    Enable in configuration::\n\n        kinto.permission_backend = kinto.core.permission.memory\n\n    :noindex:\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.flush()\n\n    def initialize_schema(self, dry_run=False):\n        # Nothing to do.\n        pass\n\n    def flush(self):\n        self._store = {}\n\n    @synchronized\n    def add_user_principal(self, user_id, principal):\n        user_key = 'user:{}'.format(user_id)\n        user_principals = self._store.get(user_key, set())\n        user_principals.add(principal)\n        self._store[user_key] = user_principals\n\n    @synchronized\n    def remove_user_principal(self, user_id, principal):\n        user_key = 'user:{}'.format(user_id)\n        user_principals = self._store.get(user_key, set())\n        try:\n            user_principals.remove(principal)\n        except KeyError:\n            pass\n        if len(user_principals) == 0:\n            if user_key in self._store:\n                del self._store[user_key]\n        else:\n            self._store[user_key] = user_principals\n\n    @synchronized\n    def remove_principal(self, principal):\n        for user_principals in self._store.values():\n            try:\n                user_principals.remove(principal)\n            except KeyError:\n                pass\n\n    @synchronized\n    def get_user_principals(self, user_id):\n        # Fetch the groups the user is in.\n        user_key = 'user:{}'.format(user_id)\n        members = self._store.get(user_key, set())\n        # Fetch the groups system.Authenticated is in.\n        group_authenticated = self._store.get('user:system.Authenticated', set())\n        return members | group_authenticated\n\n    @synchronized\n    def add_principal_to_ace(self, object_id, permission, principal):\n        permission_key = 'permission:{}:{}'.format(object_id, permission)\n        object_permission_principals = self._store.get(permission_key, set())\n        object_permission_principals.add(principal)\n        self._store[permission_key] = object_permission_principals\n\n    @synchronized\n    def remove_principal_from_ace(self, object_id, permission, principal):\n        permission_key = 'permission:{}:{}'.format(object_id, permission)\n        object_permission_principals = self._store.get(permission_key, set())\n        try:\n            object_permission_principals.remove(principal)\n        except KeyError:\n            pass\n        if len(object_permission_principals) == 0:\n            if permission_key in self._store:\n                del self._store[permission_key]\n        else:\n            self._store[permission_key] = object_permission_principals\n\n    @synchronized\n    def get_object_permission_principals(self, object_id, permission):\n        permission_key = 'permission:{}:{}'.format(object_id, permission)\n        members = self._store.get(permission_key, set())\n        return members\n\n    @synchronized\n    def get_accessible_objects(self, principals, bound_permissions=None, with_children=True):\n        principals = set(principals)\n        candidates = []\n        if bound_permissions is None:\n            for key, value in self._store.items():\n                _, object_id, permission = key.split(':', 2)\n                candidates.append((object_id, permission, value))\n        else:\n            for pattern, perm in bound_permissions:\n                id_match = '.*' if with_children else '[^/]+'\n                regexp = re.compile('^{}$'.format(pattern.replace('*', id_match)))\n                for key, value in self._store.items():\n                    if key.endswith(perm):\n                        object_id = key.split(':')[1]\n                        if regexp.match(object_id):\n                            candidates.append((object_id, perm, value))\n\n        perms_by_object_id = {}\n        for (object_id, perm, value) in candidates:\n            if len(principals & value) > 0:\n                perms_by_object_id.setdefault(object_id, set()).add(perm)\n        return perms_by_object_id\n\n    @synchronized\n    def get_authorized_principals(self, bound_permissions):\n        principals = set()\n        for obj_id, perm in bound_permissions:\n            principals |= self.get_object_permission_principals(obj_id, perm)\n        return principals\n\n    @synchronized\n    def get_objects_permissions(self, objects_ids, permissions=None):\n        result = []\n        for object_id in objects_ids:\n            if permissions is None:\n                aces = [k for k in self._store.keys()\n                        if k.startswith('permission:{}:'.format(object_id))]\n            else:\n                aces = ['permission:{}:{}'.format(object_id, permission)\n                        for permission in permissions]\n            perms = {}\n            for ace in aces:\n                # Should work with 'permission:/url/id:record:create'.\n                permission = ace.split(':', 2)[2]\n                perms[permission] = set(self._store[ace])\n            result.append(perms)\n        return result\n\n    @synchronized\n    def replace_object_permissions(self, object_id, permissions):\n        for permission, principals in permissions.items():\n            permission_key = 'permission:{}:{}'.format(object_id, permission)\n            if permission_key in self._store and len(principals) == 0:\n                del self._store[permission_key]\n            elif principals:\n                self._store[permission_key] = set(principals)\n        return permissions\n\n    @synchronized\n    def delete_object_permissions(self, *object_id_list):\n        to_delete = []\n        for key in self._store.keys():\n            object_id = key.split(':')[1]\n            for pattern in object_id_list:\n                regexp = re.compile('^{}$'.format(pattern.replace('*', '.*')))\n                if regexp.match(object_id):\n                    to_delete.append(key)\n        for k in to_delete:\n            del self._store[k]\n\n\ndef load_from_config(config):\n    return Permission()\n", "path": "kinto/core/permission/memory.py"}]}