prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  synapse returns undocumented `device` property from `GET /_matrix/client/v3/pushrules/`
  Synapse's response to a `/pushrules` query looks something like:
  
  ```json5
  [
    "global": {
      "content": { /*... */ },
      "override": { /*... */ },
      "room": { /*... */ },
      "sender": { /*... */ },
      "underride": { /*... */ }
    },
    "device": {}
  ]
  ```
  
  This `device` property is not [specced](https://spec.matrix.org/v1.2/client-server-api/#get_matrixclientv3pushrules) and should be removed.
  
  
  
  
  </issue>
  <code>
  [start of synapse/push/clientformat.py]
  1 # Copyright 2016 OpenMarket Ltd
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 #
  7 #     http://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 
  15 import copy
  16 from typing import Any, Dict, List, Optional
  17 
  18 from synapse.push.rulekinds import PRIORITY_CLASS_INVERSE_MAP, PRIORITY_CLASS_MAP
  19 from synapse.synapse_rust.push import FilteredPushRules, PushRule
  20 from synapse.types import UserID
  21 
  22 
  23 def format_push_rules_for_user(
  24     user: UserID, ruleslist: FilteredPushRules
  25 ) -> Dict[str, Dict[str, list]]:
  26     """Converts a list of rawrules and a enabled map into nested dictionaries
  27     to match the Matrix client-server format for push rules"""
  28 
  29     rules: Dict[str, Dict[str, List[Dict[str, Any]]]] = {
  30         "global": {},
  31         "device": {},
  32     }
  33 
  34     rules["global"] = _add_empty_priority_class_arrays(rules["global"])
  35 
  36     for r, enabled in ruleslist.rules():
  37         template_name = _priority_class_to_template_name(r.priority_class)
  38 
  39         rulearray = rules["global"][template_name]
  40 
  41         template_rule = _rule_to_template(r)
  42         if not template_rule:
  43             continue
  44 
  45         rulearray.append(template_rule)
  46 
  47         pattern_type = template_rule.pop("pattern_type", None)
  48         if pattern_type == "user_id":
  49             template_rule["pattern"] = user.to_string()
  50         elif pattern_type == "user_localpart":
  51             template_rule["pattern"] = user.localpart
  52 
  53         template_rule["enabled"] = enabled
  54 
  55         if "conditions" not in template_rule:
  56             # Not all formatted rules have explicit conditions, e.g. "room"
  57             # rules omit them as they can be derived from the kind and rule ID.
  58             #
  59             # If the formatted rule has no conditions then we can skip the
  60             # formatting of conditions.
  61             continue
  62 
  63         # Remove internal stuff.
  64         template_rule["conditions"] = copy.deepcopy(template_rule["conditions"])
  65         for c in template_rule["conditions"]:
  66             c.pop("_cache_key", None)
  67 
  68             pattern_type = c.pop("pattern_type", None)
  69             if pattern_type == "user_id":
  70                 c["pattern"] = user.to_string()
  71             elif pattern_type == "user_localpart":
  72                 c["pattern"] = user.localpart
  73 
  74             sender_type = c.pop("sender_type", None)
  75             if sender_type == "user_id":
  76                 c["sender"] = user.to_string()
  77 
  78     return rules
  79 
  80 
  81 def _add_empty_priority_class_arrays(d: Dict[str, list]) -> Dict[str, list]:
  82     for pc in PRIORITY_CLASS_MAP.keys():
  83         d[pc] = []
  84     return d
  85 
  86 
  87 def _rule_to_template(rule: PushRule) -> Optional[Dict[str, Any]]:
  88     templaterule: Dict[str, Any]
  89 
  90     unscoped_rule_id = _rule_id_from_namespaced(rule.rule_id)
  91 
  92     template_name = _priority_class_to_template_name(rule.priority_class)
  93     if template_name in ["override", "underride"]:
  94         templaterule = {"conditions": rule.conditions, "actions": rule.actions}
  95     elif template_name in ["sender", "room"]:
  96         templaterule = {"actions": rule.actions}
  97         unscoped_rule_id = rule.conditions[0]["pattern"]
  98     elif template_name == "content":
  99         if len(rule.conditions) != 1:
  100             return None
  101         thecond = rule.conditions[0]
  102 
  103         templaterule = {"actions": rule.actions}
  104         if "pattern" in thecond:
  105             templaterule["pattern"] = thecond["pattern"]
  106         elif "pattern_type" in thecond:
  107             templaterule["pattern_type"] = thecond["pattern_type"]
  108         else:
  109             return None
  110     else:
  111         # This should not be reached unless this function is not kept in sync
  112         # with PRIORITY_CLASS_INVERSE_MAP.
  113         raise ValueError("Unexpected template_name: %s" % (template_name,))
  114 
  115     templaterule["rule_id"] = unscoped_rule_id
  116     templaterule["default"] = rule.default
  117     return templaterule
  118 
  119 
  120 def _rule_id_from_namespaced(in_rule_id: str) -> str:
  121     return in_rule_id.split("/")[-1]
  122 
  123 
  124 def _priority_class_to_template_name(pc: int) -> str:
  125     return PRIORITY_CLASS_INVERSE_MAP[pc]
  126
  [end of synapse/push/clientformat.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/synapse/push/clientformat.py b/synapse/push/clientformat.py
  --- a/synapse/push/clientformat.py
  +++ b/synapse/push/clientformat.py
  @@ -26,10 +26,7 @@
       """Converts a list of rawrules and a enabled map into nested dictionaries
       to match the Matrix client-server format for push rules"""
   
  -    rules: Dict[str, Dict[str, List[Dict[str, Any]]]] = {
  -        "global": {},
  -        "device": {},
  -    }
  +    rules: Dict[str, Dict[str, List[Dict[str, Any]]]] = {"global": {}}
   
       rules["global"] = _add_empty_priority_class_arrays(rules["global"])
  
verification_info: {"golden_diff": "diff --git a/synapse/push/clientformat.py b/synapse/push/clientformat.py\n--- a/synapse/push/clientformat.py\n+++ b/synapse/push/clientformat.py\n@@ -26,10 +26,7 @@\n     \"\"\"Converts a list of rawrules and a enabled map into nested dictionaries\n     to match the Matrix client-server format for push rules\"\"\"\n \n-    rules: Dict[str, Dict[str, List[Dict[str, Any]]]] = {\n-        \"global\": {},\n-        \"device\": {},\n-    }\n+    rules: Dict[str, Dict[str, List[Dict[str, Any]]]] = {\"global\": {}}\n \n     rules[\"global\"] = _add_empty_priority_class_arrays(rules[\"global\"])\n", "issue": "synapse returns undocumented `device` property from `GET /_matrix/client/v3/pushrules/`\nSynapse's response to a `/pushrules` query looks something like:\r\n\r\n```json5\r\n[\r\n  \"global\": {\r\n    \"content\": { /*... */ },\r\n    \"override\": { /*... */ },\r\n    \"room\": { /*... */ },\r\n    \"sender\": { /*... */ },\r\n    \"underride\": { /*... */ }\r\n  },\r\n  \"device\": {}\r\n]\r\n```\r\n\r\nThis `device` property is not [specced](https://spec.matrix.org/v1.2/client-server-api/#get_matrixclientv3pushrules) and should be removed.\r\n\r\n\r\n\n", "before_files": [{"content": "# Copyright 2016 OpenMarket Ltd\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport copy\nfrom typing import Any, Dict, List, Optional\n\nfrom synapse.push.rulekinds import PRIORITY_CLASS_INVERSE_MAP, PRIORITY_CLASS_MAP\nfrom synapse.synapse_rust.push import FilteredPushRules, PushRule\nfrom synapse.types import UserID\n\n\ndef format_push_rules_for_user(\n    user: UserID, ruleslist: FilteredPushRules\n) -> Dict[str, Dict[str, list]]:\n    \"\"\"Converts a list of rawrules and a enabled map into nested dictionaries\n    to match the Matrix client-server format for push rules\"\"\"\n\n    rules: Dict[str, Dict[str, List[Dict[str, Any]]]] = {\n        \"global\": {},\n        \"device\": {},\n    }\n\n    rules[\"global\"] = _add_empty_priority_class_arrays(rules[\"global\"])\n\n    for r, enabled in ruleslist.rules():\n        template_name = _priority_class_to_template_name(r.priority_class)\n\n        rulearray = rules[\"global\"][template_name]\n\n        template_rule = _rule_to_template(r)\n        if not template_rule:\n            continue\n\n        rulearray.append(template_rule)\n\n        pattern_type = template_rule.pop(\"pattern_type\", None)\n        if pattern_type == \"user_id\":\n            template_rule[\"pattern\"] = user.to_string()\n        elif pattern_type == \"user_localpart\":\n            template_rule[\"pattern\"] = user.localpart\n\n        template_rule[\"enabled\"] = enabled\n\n        if \"conditions\" not in template_rule:\n            # Not all formatted rules have explicit conditions, e.g. \"room\"\n            # rules omit them as they can be derived from the kind and rule ID.\n            #\n            # If the formatted rule has no conditions then we can skip the\n            # formatting of conditions.\n            continue\n\n        # Remove internal stuff.\n        template_rule[\"conditions\"] = copy.deepcopy(template_rule[\"conditions\"])\n        for c in template_rule[\"conditions\"]:\n            c.pop(\"_cache_key\", None)\n\n            pattern_type = c.pop(\"pattern_type\", None)\n            if pattern_type == \"user_id\":\n                c[\"pattern\"] = user.to_string()\n            elif pattern_type == \"user_localpart\":\n                c[\"pattern\"] = user.localpart\n\n            sender_type = c.pop(\"sender_type\", None)\n            if sender_type == \"user_id\":\n                c[\"sender\"] = user.to_string()\n\n    return rules\n\n\ndef _add_empty_priority_class_arrays(d: Dict[str, list]) -> Dict[str, list]:\n    for pc in PRIORITY_CLASS_MAP.keys():\n        d[pc] = []\n    return d\n\n\ndef _rule_to_template(rule: PushRule) -> Optional[Dict[str, Any]]:\n    templaterule: Dict[str, Any]\n\n    unscoped_rule_id = _rule_id_from_namespaced(rule.rule_id)\n\n    template_name = _priority_class_to_template_name(rule.priority_class)\n    if template_name in [\"override\", \"underride\"]:\n        templaterule = {\"conditions\": rule.conditions, \"actions\": rule.actions}\n    elif template_name in [\"sender\", \"room\"]:\n        templaterule = {\"actions\": rule.actions}\n        unscoped_rule_id = rule.conditions[0][\"pattern\"]\n    elif template_name == \"content\":\n        if len(rule.conditions) != 1:\n            return None\n        thecond = rule.conditions[0]\n\n        templaterule = {\"actions\": rule.actions}\n        if \"pattern\" in thecond:\n            templaterule[\"pattern\"] = thecond[\"pattern\"]\n        elif \"pattern_type\" in thecond:\n            templaterule[\"pattern_type\"] = thecond[\"pattern_type\"]\n        else:\n            return None\n    else:\n        # This should not be reached unless this function is not kept in sync\n        # with PRIORITY_CLASS_INVERSE_MAP.\n        raise ValueError(\"Unexpected template_name: %s\" % (template_name,))\n\n    templaterule[\"rule_id\"] = unscoped_rule_id\n    templaterule[\"default\"] = rule.default\n    return templaterule\n\n\ndef _rule_id_from_namespaced(in_rule_id: str) -> str:\n    return in_rule_id.split(\"/\")[-1]\n\n\ndef _priority_class_to_template_name(pc: int) -> str:\n    return PRIORITY_CLASS_INVERSE_MAP[pc]\n", "path": "synapse/push/clientformat.py"}]}