prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  sample doc in #11561 is malformatted
  see https://github.com/matrix-org/synapse/pull/11561#pullrequestreview-851817482
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `synapse/config/api.py`
  Content:
  ```
  1 # Copyright 2015-2021 The Matrix.org Foundation C.I.C.
  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 logging
  16 from typing import Iterable
  17 
  18 from synapse.api.constants import EventTypes
  19 from synapse.config._base import Config, ConfigError
  20 from synapse.config._util import validate_config
  21 from synapse.types import JsonDict
  22 
  23 logger = logging.getLogger(__name__)
  24 
  25 
  26 class ApiConfig(Config):
  27     section = "api"
  28 
  29     def read_config(self, config: JsonDict, **kwargs):
  30         validate_config(_MAIN_SCHEMA, config, ())
  31         self.room_prejoin_state = list(self._get_prejoin_state_types(config))
  32         self.track_puppeted_user_ips = config.get("track_puppeted_user_ips", False)
  33 
  34     def generate_config_section(cls, **kwargs) -> str:
  35         formatted_default_state_types = "\n".join(
  36             "           # - %s" % (t,) for t in _DEFAULT_PREJOIN_STATE_TYPES
  37         )
  38 
  39         return """\
  40         ## API Configuration ##
  41 
  42         # Controls for the state that is shared with users who receive an invite
  43         # to a room
  44         #
  45         room_prejoin_state:
  46            # By default, the following state event types are shared with users who
  47            # receive invites to the room:
  48            #
  49 %(formatted_default_state_types)s
  50            #
  51            # Uncomment the following to disable these defaults (so that only the event
  52            # types listed in 'additional_event_types' are shared). Defaults to 'false'.
  53            #
  54            #disable_default_event_types: true
  55 
  56            # Additional state event types to share with users when they are invited
  57            # to a room.
  58            #
  59            # By default, this list is empty (so only the default event types are shared).
  60            #
  61            #additional_event_types:
  62            #  - org.example.custom.event.type
  63 
  64         # By default when puppeting another user, the user who has created the
  65         # access token for puppeting is tracked. If this is enabled, both
  66         # requests are tracked. Implicitly enables MAU tracking for puppeted users.
  67         # Uncomment to also track puppeted user IP's.
  68         #
  69         #track_puppeted_user_ips: true
  70         """ % {
  71             "formatted_default_state_types": formatted_default_state_types
  72         }
  73 
  74     def _get_prejoin_state_types(self, config: JsonDict) -> Iterable[str]:
  75         """Get the event types to include in the prejoin state
  76 
  77         Parses the config and returns an iterable of the event types to be included.
  78         """
  79         room_prejoin_state_config = config.get("room_prejoin_state") or {}
  80 
  81         # backwards-compatibility support for room_invite_state_types
  82         if "room_invite_state_types" in config:
  83             # if both "room_invite_state_types" and "room_prejoin_state" are set, then
  84             # we don't really know what to do.
  85             if room_prejoin_state_config:
  86                 raise ConfigError(
  87                     "Can't specify both 'room_invite_state_types' and 'room_prejoin_state' "
  88                     "in config"
  89                 )
  90 
  91             logger.warning(_ROOM_INVITE_STATE_TYPES_WARNING)
  92 
  93             yield from config["room_invite_state_types"]
  94             return
  95 
  96         if not room_prejoin_state_config.get("disable_default_event_types"):
  97             yield from _DEFAULT_PREJOIN_STATE_TYPES
  98 
  99         yield from room_prejoin_state_config.get("additional_event_types", [])
  100 
  101 
  102 _ROOM_INVITE_STATE_TYPES_WARNING = """\
  103 WARNING: The 'room_invite_state_types' configuration setting is now deprecated,
  104 and replaced with 'room_prejoin_state'. New features may not work correctly
  105 unless 'room_invite_state_types' is removed. See the sample configuration file for
  106 details of 'room_prejoin_state'.
  107 --------------------------------------------------------------------------------
  108 """
  109 
  110 _DEFAULT_PREJOIN_STATE_TYPES = [
  111     EventTypes.JoinRules,
  112     EventTypes.CanonicalAlias,
  113     EventTypes.RoomAvatar,
  114     EventTypes.RoomEncryption,
  115     EventTypes.Name,
  116     # Per MSC1772.
  117     EventTypes.Create,
  118     # Per MSC3173.
  119     EventTypes.Topic,
  120 ]
  121 
  122 
  123 # room_prejoin_state can either be None (as it is in the default config), or
  124 # an object containing other config settings
  125 _ROOM_PREJOIN_STATE_CONFIG_SCHEMA = {
  126     "oneOf": [
  127         {
  128             "type": "object",
  129             "properties": {
  130                 "disable_default_event_types": {"type": "boolean"},
  131                 "additional_event_types": {
  132                     "type": "array",
  133                     "items": {"type": "string"},
  134                 },
  135             },
  136         },
  137         {"type": "null"},
  138     ]
  139 }
  140 
  141 # the legacy room_invite_state_types setting
  142 _ROOM_INVITE_STATE_TYPES_SCHEMA = {"type": "array", "items": {"type": "string"}}
  143 
  144 _MAIN_SCHEMA = {
  145     "type": "object",
  146     "properties": {
  147         "room_prejoin_state": _ROOM_PREJOIN_STATE_CONFIG_SCHEMA,
  148         "room_invite_state_types": _ROOM_INVITE_STATE_TYPES_SCHEMA,
  149         "track_puppeted_user_ips": {
  150             "type": "boolean",
  151         },
  152     },
  153 }
  154
  ```
  --- 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/synapse/config/api.py b/synapse/config/api.py
  --- a/synapse/config/api.py
  +++ b/synapse/config/api.py
  @@ -61,10 +61,18 @@
              #additional_event_types:
              #  - org.example.custom.event.type
   
  -        # By default when puppeting another user, the user who has created the
  -        # access token for puppeting is tracked. If this is enabled, both
  -        # requests are tracked. Implicitly enables MAU tracking for puppeted users.
  -        # Uncomment to also track puppeted user IP's.
  +        # We record the IP address of clients used to access the API for various
  +        # reasons, including displaying it to the user in the "Where you're signed in"
  +        # dialog.
  +        #
  +        # By default, when puppeting another user via the admin API, the client IP
  +        # address is recorded against the user who created the access token (ie, the
  +        # admin user), and *not* the puppeted user.
  +        #
  +        # Uncomment the following to also record the IP address against the puppeted
  +        # user. (This also means that the puppeted user will count as an "active" user
  +        # for the purpose of monthly active user tracking - see 'limit_usage_by_mau' etc
  +        # above.)
           #
           #track_puppeted_user_ips: true
           """ % {
  
verification_info: {"golden_diff": "diff --git a/synapse/config/api.py b/synapse/config/api.py\n--- a/synapse/config/api.py\n+++ b/synapse/config/api.py\n@@ -61,10 +61,18 @@\n            #additional_event_types:\n            #  - org.example.custom.event.type\n \n-        # By default when puppeting another user, the user who has created the\n-        # access token for puppeting is tracked. If this is enabled, both\n-        # requests are tracked. Implicitly enables MAU tracking for puppeted users.\n-        # Uncomment to also track puppeted user IP's.\n+        # We record the IP address of clients used to access the API for various\n+        # reasons, including displaying it to the user in the \"Where you're signed in\"\n+        # dialog.\n+        #\n+        # By default, when puppeting another user via the admin API, the client IP\n+        # address is recorded against the user who created the access token (ie, the\n+        # admin user), and *not* the puppeted user.\n+        #\n+        # Uncomment the following to also record the IP address against the puppeted\n+        # user. (This also means that the puppeted user will count as an \"active\" user\n+        # for the purpose of monthly active user tracking - see 'limit_usage_by_mau' etc\n+        # above.)\n         #\n         #track_puppeted_user_ips: true\n         \"\"\" % {\n", "issue": "sample doc in #11561 is malformatted\nsee https://github.com/matrix-org/synapse/pull/11561#pullrequestreview-851817482\n", "before_files": [{"content": "# Copyright 2015-2021 The Matrix.org Foundation C.I.C.\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 logging\nfrom typing import Iterable\n\nfrom synapse.api.constants import EventTypes\nfrom synapse.config._base import Config, ConfigError\nfrom synapse.config._util import validate_config\nfrom synapse.types import JsonDict\n\nlogger = logging.getLogger(__name__)\n\n\nclass ApiConfig(Config):\n    section = \"api\"\n\n    def read_config(self, config: JsonDict, **kwargs):\n        validate_config(_MAIN_SCHEMA, config, ())\n        self.room_prejoin_state = list(self._get_prejoin_state_types(config))\n        self.track_puppeted_user_ips = config.get(\"track_puppeted_user_ips\", False)\n\n    def generate_config_section(cls, **kwargs) -> str:\n        formatted_default_state_types = \"\\n\".join(\n            \"           # - %s\" % (t,) for t in _DEFAULT_PREJOIN_STATE_TYPES\n        )\n\n        return \"\"\"\\\n        ## API Configuration ##\n\n        # Controls for the state that is shared with users who receive an invite\n        # to a room\n        #\n        room_prejoin_state:\n           # By default, the following state event types are shared with users who\n           # receive invites to the room:\n           #\n%(formatted_default_state_types)s\n           #\n           # Uncomment the following to disable these defaults (so that only the event\n           # types listed in 'additional_event_types' are shared). Defaults to 'false'.\n           #\n           #disable_default_event_types: true\n\n           # Additional state event types to share with users when they are invited\n           # to a room.\n           #\n           # By default, this list is empty (so only the default event types are shared).\n           #\n           #additional_event_types:\n           #  - org.example.custom.event.type\n\n        # By default when puppeting another user, the user who has created the\n        # access token for puppeting is tracked. If this is enabled, both\n        # requests are tracked. Implicitly enables MAU tracking for puppeted users.\n        # Uncomment to also track puppeted user IP's.\n        #\n        #track_puppeted_user_ips: true\n        \"\"\" % {\n            \"formatted_default_state_types\": formatted_default_state_types\n        }\n\n    def _get_prejoin_state_types(self, config: JsonDict) -> Iterable[str]:\n        \"\"\"Get the event types to include in the prejoin state\n\n        Parses the config and returns an iterable of the event types to be included.\n        \"\"\"\n        room_prejoin_state_config = config.get(\"room_prejoin_state\") or {}\n\n        # backwards-compatibility support for room_invite_state_types\n        if \"room_invite_state_types\" in config:\n            # if both \"room_invite_state_types\" and \"room_prejoin_state\" are set, then\n            # we don't really know what to do.\n            if room_prejoin_state_config:\n                raise ConfigError(\n                    \"Can't specify both 'room_invite_state_types' and 'room_prejoin_state' \"\n                    \"in config\"\n                )\n\n            logger.warning(_ROOM_INVITE_STATE_TYPES_WARNING)\n\n            yield from config[\"room_invite_state_types\"]\n            return\n\n        if not room_prejoin_state_config.get(\"disable_default_event_types\"):\n            yield from _DEFAULT_PREJOIN_STATE_TYPES\n\n        yield from room_prejoin_state_config.get(\"additional_event_types\", [])\n\n\n_ROOM_INVITE_STATE_TYPES_WARNING = \"\"\"\\\nWARNING: The 'room_invite_state_types' configuration setting is now deprecated,\nand replaced with 'room_prejoin_state'. New features may not work correctly\nunless 'room_invite_state_types' is removed. See the sample configuration file for\ndetails of 'room_prejoin_state'.\n--------------------------------------------------------------------------------\n\"\"\"\n\n_DEFAULT_PREJOIN_STATE_TYPES = [\n    EventTypes.JoinRules,\n    EventTypes.CanonicalAlias,\n    EventTypes.RoomAvatar,\n    EventTypes.RoomEncryption,\n    EventTypes.Name,\n    # Per MSC1772.\n    EventTypes.Create,\n    # Per MSC3173.\n    EventTypes.Topic,\n]\n\n\n# room_prejoin_state can either be None (as it is in the default config), or\n# an object containing other config settings\n_ROOM_PREJOIN_STATE_CONFIG_SCHEMA = {\n    \"oneOf\": [\n        {\n            \"type\": \"object\",\n            \"properties\": {\n                \"disable_default_event_types\": {\"type\": \"boolean\"},\n                \"additional_event_types\": {\n                    \"type\": \"array\",\n                    \"items\": {\"type\": \"string\"},\n                },\n            },\n        },\n        {\"type\": \"null\"},\n    ]\n}\n\n# the legacy room_invite_state_types setting\n_ROOM_INVITE_STATE_TYPES_SCHEMA = {\"type\": \"array\", \"items\": {\"type\": \"string\"}}\n\n_MAIN_SCHEMA = {\n    \"type\": \"object\",\n    \"properties\": {\n        \"room_prejoin_state\": _ROOM_PREJOIN_STATE_CONFIG_SCHEMA,\n        \"room_invite_state_types\": _ROOM_INVITE_STATE_TYPES_SCHEMA,\n        \"track_puppeted_user_ips\": {\n            \"type\": \"boolean\",\n        },\n    },\n}\n", "path": "synapse/config/api.py"}], "after_files": [{"content": "# Copyright 2015-2021 The Matrix.org Foundation C.I.C.\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 logging\nfrom typing import Iterable\n\nfrom synapse.api.constants import EventTypes\nfrom synapse.config._base import Config, ConfigError\nfrom synapse.config._util import validate_config\nfrom synapse.types import JsonDict\n\nlogger = logging.getLogger(__name__)\n\n\nclass ApiConfig(Config):\n    section = \"api\"\n\n    def read_config(self, config: JsonDict, **kwargs):\n        validate_config(_MAIN_SCHEMA, config, ())\n        self.room_prejoin_state = list(self._get_prejoin_state_types(config))\n        self.track_puppeted_user_ips = config.get(\"track_puppeted_user_ips\", False)\n\n    def generate_config_section(cls, **kwargs) -> str:\n        formatted_default_state_types = \"\\n\".join(\n            \"           # - %s\" % (t,) for t in _DEFAULT_PREJOIN_STATE_TYPES\n        )\n\n        return \"\"\"\\\n        ## API Configuration ##\n\n        # Controls for the state that is shared with users who receive an invite\n        # to a room\n        #\n        room_prejoin_state:\n           # By default, the following state event types are shared with users who\n           # receive invites to the room:\n           #\n%(formatted_default_state_types)s\n           #\n           # Uncomment the following to disable these defaults (so that only the event\n           # types listed in 'additional_event_types' are shared). Defaults to 'false'.\n           #\n           #disable_default_event_types: true\n\n           # Additional state event types to share with users when they are invited\n           # to a room.\n           #\n           # By default, this list is empty (so only the default event types are shared).\n           #\n           #additional_event_types:\n           #  - org.example.custom.event.type\n\n        # We record the IP address of clients used to access the API for various\n        # reasons, including displaying it to the user in the \"Where you're signed in\"\n        # dialog.\n        #\n        # By default, when puppeting another user via the admin API, the client IP\n        # address is recorded against the user who created the access token (ie, the\n        # admin user), and *not* the puppeted user.\n        #\n        # Uncomment the following to also record the IP address against the puppeted\n        # user. (This also means that the puppeted user will count as an \"active\" user\n        # for the purpose of monthly active user tracking - see 'limit_usage_by_mau' etc\n        # above.)\n        #\n        #track_puppeted_user_ips: true\n        \"\"\" % {\n            \"formatted_default_state_types\": formatted_default_state_types\n        }\n\n    def _get_prejoin_state_types(self, config: JsonDict) -> Iterable[str]:\n        \"\"\"Get the event types to include in the prejoin state\n\n        Parses the config and returns an iterable of the event types to be included.\n        \"\"\"\n        room_prejoin_state_config = config.get(\"room_prejoin_state\") or {}\n\n        # backwards-compatibility support for room_invite_state_types\n        if \"room_invite_state_types\" in config:\n            # if both \"room_invite_state_types\" and \"room_prejoin_state\" are set, then\n            # we don't really know what to do.\n            if room_prejoin_state_config:\n                raise ConfigError(\n                    \"Can't specify both 'room_invite_state_types' and 'room_prejoin_state' \"\n                    \"in config\"\n                )\n\n            logger.warning(_ROOM_INVITE_STATE_TYPES_WARNING)\n\n            yield from config[\"room_invite_state_types\"]\n            return\n\n        if not room_prejoin_state_config.get(\"disable_default_event_types\"):\n            yield from _DEFAULT_PREJOIN_STATE_TYPES\n\n        yield from room_prejoin_state_config.get(\"additional_event_types\", [])\n\n\n_ROOM_INVITE_STATE_TYPES_WARNING = \"\"\"\\\nWARNING: The 'room_invite_state_types' configuration setting is now deprecated,\nand replaced with 'room_prejoin_state'. New features may not work correctly\nunless 'room_invite_state_types' is removed. See the sample configuration file for\ndetails of 'room_prejoin_state'.\n--------------------------------------------------------------------------------\n\"\"\"\n\n_DEFAULT_PREJOIN_STATE_TYPES = [\n    EventTypes.JoinRules,\n    EventTypes.CanonicalAlias,\n    EventTypes.RoomAvatar,\n    EventTypes.RoomEncryption,\n    EventTypes.Name,\n    # Per MSC1772.\n    EventTypes.Create,\n    # Per MSC3173.\n    EventTypes.Topic,\n]\n\n\n# room_prejoin_state can either be None (as it is in the default config), or\n# an object containing other config settings\n_ROOM_PREJOIN_STATE_CONFIG_SCHEMA = {\n    \"oneOf\": [\n        {\n            \"type\": \"object\",\n            \"properties\": {\n                \"disable_default_event_types\": {\"type\": \"boolean\"},\n                \"additional_event_types\": {\n                    \"type\": \"array\",\n                    \"items\": {\"type\": \"string\"},\n                },\n            },\n        },\n        {\"type\": \"null\"},\n    ]\n}\n\n# the legacy room_invite_state_types setting\n_ROOM_INVITE_STATE_TYPES_SCHEMA = {\"type\": \"array\", \"items\": {\"type\": \"string\"}}\n\n_MAIN_SCHEMA = {\n    \"type\": \"object\",\n    \"properties\": {\n        \"room_prejoin_state\": _ROOM_PREJOIN_STATE_CONFIG_SCHEMA,\n        \"room_invite_state_types\": _ROOM_INVITE_STATE_TYPES_SCHEMA,\n        \"track_puppeted_user_ips\": {\n            \"type\": \"boolean\",\n        },\n    },\n}\n", "path": "synapse/config/api.py"}]}