prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Initialize issue_body_footer when reading issue tracker config
  It seems like we forgot to add initialization of `issue_body_footer` in https://github.com/google/clusterfuzz/blob/dfe686cde7429ed0ba482b0b0b4f27106b0a0d5f/src/appengine/libs/issue_management/issue_tracker_policy.py#L114, that's why the issues filed recently do not have the text explaining that OSS-Fuzz team doesn't read bug tracked comments and can be contacted via GitHub only.
  
  Bug example: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17216
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/appengine/libs/issue_management/issue_tracker_policy.py`
  Content:
  ```
  1 # Copyright 2019 Google LLC
  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 # Unless required by applicable law or agreed to in writing, software
  9 # distributed under the License is distributed on an "AS IS" BASIS,
  10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11 # See the License for the specific language governing permissions and
  12 # limitations under the License.
  13 """Issue tracker policy."""
  14 
  15 from builtins import object
  16 from collections import namedtuple
  17 
  18 from config import local_config
  19 
  20 Status = namedtuple('Status',
  21                     ['assigned', 'duplicate', 'wontfix', 'fixed', 'verified'])
  22 
  23 EXPECTED_STATUSES = [
  24     'assigned',
  25     'duplicate',
  26     'wontfix',
  27     'fixed',
  28     'verified',
  29     'new',
  30 ]
  31 
  32 
  33 class ConfigurationError(Exception):
  34   """Base configuration error class."""
  35 
  36 
  37 class NewIssuePolicy(object):
  38   """New issue policy."""
  39 
  40   def __init__(self):
  41     self.status = ''
  42     self.ccs = []
  43     self.labels = []
  44     self.issue_body_footer = ''
  45 
  46 
  47 def _to_str_list(values):
  48   """Convert a list to a list of strs."""
  49   return [str(value) for value in values]
  50 
  51 
  52 class IssueTrackerPolicy(object):
  53   """Represents an issue tracker policy."""
  54 
  55   def __init__(self, data):
  56     self._data = data
  57     if 'status' not in self._data:
  58       raise ConfigurationError('Status not set in policies.')
  59 
  60     if 'labels' not in self._data:
  61       raise ConfigurationError('Labels not set in policies.')
  62 
  63     for status in EXPECTED_STATUSES:
  64       if status not in self._data['status']:
  65         raise ConfigurationError(
  66             'Expected status {} is not set.'.format(status))
  67 
  68   def status(self, status_type):
  69     """Get the actual status string for the given type."""
  70     return self._data['status'][status_type]
  71 
  72   def label(self, label_type):
  73     """Get the actual label string for the given type."""
  74     label = self._data['labels'].get(label_type)
  75     if label is None:
  76       return None
  77 
  78     return str(label)
  79 
  80   def substitution_mapping(self, label):
  81     """Get an explicit substitution mapping."""
  82     if 'substitutions' not in self._data:
  83       return label
  84 
  85     mapped = self._data['substitutions'].get(label)
  86     if not mapped:
  87       return label
  88 
  89     return str(mapped)
  90 
  91   @property
  92   def deadline_policy_message(self):
  93     """Get the deadline policy message, if if exists."""
  94     return self._data.get('deadline_policy_message')
  95 
  96   def get_new_issue_properties(self, is_security, is_crash):
  97     """Get the properties to apply to a new issue."""
  98     policy = NewIssuePolicy()
  99 
  100     if 'all' in self._data:
  101       self._apply_new_issue_properties(policy, self._data['all'], is_crash)
  102 
  103     if is_security:
  104       if 'security' in self._data:
  105         self._apply_new_issue_properties(policy, self._data['security'],
  106                                          is_crash)
  107     else:
  108       if 'non_security' in self._data:
  109         self._apply_new_issue_properties(policy, self._data['non_security'],
  110                                          is_crash)
  111 
  112     return policy
  113 
  114   def _apply_new_issue_properties(self, policy, issue_type, is_crash):
  115     """Apply issue policies."""
  116     if not issue_type:
  117       return
  118 
  119     if 'status' in issue_type:
  120       policy.status = self._data['status'][issue_type['status']]
  121 
  122     if 'ccs' in issue_type:
  123       policy.labels.extend(issue_type['ccs'])
  124 
  125     labels = issue_type.get('labels')
  126     if labels:
  127       policy.labels.extend(_to_str_list(labels))
  128 
  129     if is_crash:
  130       crash_labels = issue_type.get('crash_labels')
  131       if crash_labels:
  132         policy.labels.extend(_to_str_list(crash_labels))
  133     else:
  134       non_crash_labels = issue_type.get('non_crash_labels')
  135       if non_crash_labels:
  136         policy.labels.extend(_to_str_list(non_crash_labels))
  137 
  138   def get_existing_issue_properties(self):
  139     """Get the properties to apply to a new issue."""
  140     policy = NewIssuePolicy()
  141 
  142     if 'existing' in self._data:
  143       self._apply_new_issue_properties(policy, self._data['existing'], False)
  144 
  145     return policy
  146 
  147 
  148 def get(project_name):
  149   """Get policy."""
  150   issue_tracker_config = local_config.IssueTrackerConfig()
  151   project_config = issue_tracker_config.get(project_name)
  152   if not project_config:
  153     raise ConfigurationError(
  154         'Issue tracker for {} does not exist'.format(project_name))
  155 
  156   if not 'policies' in project_config:
  157     raise ConfigurationError(
  158         'Policies for {} do not exist'.format(project_name))
  159 
  160   return IssueTrackerPolicy(project_config['policies'])
  161 
  162 
  163 def get_empty():
  164   """Get an empty policy."""
  165   return IssueTrackerPolicy({
  166       'status': {
  167           'assigned': 'unused',
  168           'duplicate': 'unused',
  169           'wontfix': 'unused',
  170           'fixed': 'unused',
  171           'verified': 'unused',
  172           'new': 'unused',
  173       },
  174       'labels': {},
  175   })
  176
  ```
  --- 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/src/appengine/libs/issue_management/issue_tracker_policy.py b/src/appengine/libs/issue_management/issue_tracker_policy.py
  --- a/src/appengine/libs/issue_management/issue_tracker_policy.py
  +++ b/src/appengine/libs/issue_management/issue_tracker_policy.py
  @@ -126,6 +126,10 @@
       if labels:
         policy.labels.extend(_to_str_list(labels))
   
  +    issue_body_footer = issue_type.get('issue_body_footer')
  +    if issue_body_footer:
  +      policy.issue_body_footer = issue_body_footer
  +
       if is_crash:
         crash_labels = issue_type.get('crash_labels')
         if crash_labels:
  
verification_info: {"golden_diff": "diff --git a/src/appengine/libs/issue_management/issue_tracker_policy.py b/src/appengine/libs/issue_management/issue_tracker_policy.py\n--- a/src/appengine/libs/issue_management/issue_tracker_policy.py\n+++ b/src/appengine/libs/issue_management/issue_tracker_policy.py\n@@ -126,6 +126,10 @@\n     if labels:\n       policy.labels.extend(_to_str_list(labels))\n \n+    issue_body_footer = issue_type.get('issue_body_footer')\n+    if issue_body_footer:\n+      policy.issue_body_footer = issue_body_footer\n+\n     if is_crash:\n       crash_labels = issue_type.get('crash_labels')\n       if crash_labels:\n", "issue": "Initialize issue_body_footer when reading issue tracker config\nIt seems like we forgot to add initialization of `issue_body_footer` in https://github.com/google/clusterfuzz/blob/dfe686cde7429ed0ba482b0b0b4f27106b0a0d5f/src/appengine/libs/issue_management/issue_tracker_policy.py#L114, that's why the issues filed recently do not have the text explaining that OSS-Fuzz team doesn't read bug tracked comments and can be contacted via GitHub only.\r\n\r\nBug example: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=17216\n", "before_files": [{"content": "# Copyright 2019 Google LLC\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# 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\"\"\"Issue tracker policy.\"\"\"\n\nfrom builtins import object\nfrom collections import namedtuple\n\nfrom config import local_config\n\nStatus = namedtuple('Status',\n                    ['assigned', 'duplicate', 'wontfix', 'fixed', 'verified'])\n\nEXPECTED_STATUSES = [\n    'assigned',\n    'duplicate',\n    'wontfix',\n    'fixed',\n    'verified',\n    'new',\n]\n\n\nclass ConfigurationError(Exception):\n  \"\"\"Base configuration error class.\"\"\"\n\n\nclass NewIssuePolicy(object):\n  \"\"\"New issue policy.\"\"\"\n\n  def __init__(self):\n    self.status = ''\n    self.ccs = []\n    self.labels = []\n    self.issue_body_footer = ''\n\n\ndef _to_str_list(values):\n  \"\"\"Convert a list to a list of strs.\"\"\"\n  return [str(value) for value in values]\n\n\nclass IssueTrackerPolicy(object):\n  \"\"\"Represents an issue tracker policy.\"\"\"\n\n  def __init__(self, data):\n    self._data = data\n    if 'status' not in self._data:\n      raise ConfigurationError('Status not set in policies.')\n\n    if 'labels' not in self._data:\n      raise ConfigurationError('Labels not set in policies.')\n\n    for status in EXPECTED_STATUSES:\n      if status not in self._data['status']:\n        raise ConfigurationError(\n            'Expected status {} is not set.'.format(status))\n\n  def status(self, status_type):\n    \"\"\"Get the actual status string for the given type.\"\"\"\n    return self._data['status'][status_type]\n\n  def label(self, label_type):\n    \"\"\"Get the actual label string for the given type.\"\"\"\n    label = self._data['labels'].get(label_type)\n    if label is None:\n      return None\n\n    return str(label)\n\n  def substitution_mapping(self, label):\n    \"\"\"Get an explicit substitution mapping.\"\"\"\n    if 'substitutions' not in self._data:\n      return label\n\n    mapped = self._data['substitutions'].get(label)\n    if not mapped:\n      return label\n\n    return str(mapped)\n\n  @property\n  def deadline_policy_message(self):\n    \"\"\"Get the deadline policy message, if if exists.\"\"\"\n    return self._data.get('deadline_policy_message')\n\n  def get_new_issue_properties(self, is_security, is_crash):\n    \"\"\"Get the properties to apply to a new issue.\"\"\"\n    policy = NewIssuePolicy()\n\n    if 'all' in self._data:\n      self._apply_new_issue_properties(policy, self._data['all'], is_crash)\n\n    if is_security:\n      if 'security' in self._data:\n        self._apply_new_issue_properties(policy, self._data['security'],\n                                         is_crash)\n    else:\n      if 'non_security' in self._data:\n        self._apply_new_issue_properties(policy, self._data['non_security'],\n                                         is_crash)\n\n    return policy\n\n  def _apply_new_issue_properties(self, policy, issue_type, is_crash):\n    \"\"\"Apply issue policies.\"\"\"\n    if not issue_type:\n      return\n\n    if 'status' in issue_type:\n      policy.status = self._data['status'][issue_type['status']]\n\n    if 'ccs' in issue_type:\n      policy.labels.extend(issue_type['ccs'])\n\n    labels = issue_type.get('labels')\n    if labels:\n      policy.labels.extend(_to_str_list(labels))\n\n    if is_crash:\n      crash_labels = issue_type.get('crash_labels')\n      if crash_labels:\n        policy.labels.extend(_to_str_list(crash_labels))\n    else:\n      non_crash_labels = issue_type.get('non_crash_labels')\n      if non_crash_labels:\n        policy.labels.extend(_to_str_list(non_crash_labels))\n\n  def get_existing_issue_properties(self):\n    \"\"\"Get the properties to apply to a new issue.\"\"\"\n    policy = NewIssuePolicy()\n\n    if 'existing' in self._data:\n      self._apply_new_issue_properties(policy, self._data['existing'], False)\n\n    return policy\n\n\ndef get(project_name):\n  \"\"\"Get policy.\"\"\"\n  issue_tracker_config = local_config.IssueTrackerConfig()\n  project_config = issue_tracker_config.get(project_name)\n  if not project_config:\n    raise ConfigurationError(\n        'Issue tracker for {} does not exist'.format(project_name))\n\n  if not 'policies' in project_config:\n    raise ConfigurationError(\n        'Policies for {} do not exist'.format(project_name))\n\n  return IssueTrackerPolicy(project_config['policies'])\n\n\ndef get_empty():\n  \"\"\"Get an empty policy.\"\"\"\n  return IssueTrackerPolicy({\n      'status': {\n          'assigned': 'unused',\n          'duplicate': 'unused',\n          'wontfix': 'unused',\n          'fixed': 'unused',\n          'verified': 'unused',\n          'new': 'unused',\n      },\n      'labels': {},\n  })\n", "path": "src/appengine/libs/issue_management/issue_tracker_policy.py"}], "after_files": [{"content": "# Copyright 2019 Google LLC\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# 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\"\"\"Issue tracker policy.\"\"\"\n\nfrom builtins import object\nfrom collections import namedtuple\n\nfrom config import local_config\n\nStatus = namedtuple('Status',\n                    ['assigned', 'duplicate', 'wontfix', 'fixed', 'verified'])\n\nEXPECTED_STATUSES = [\n    'assigned',\n    'duplicate',\n    'wontfix',\n    'fixed',\n    'verified',\n    'new',\n]\n\n\nclass ConfigurationError(Exception):\n  \"\"\"Base configuration error class.\"\"\"\n\n\nclass NewIssuePolicy(object):\n  \"\"\"New issue policy.\"\"\"\n\n  def __init__(self):\n    self.status = ''\n    self.ccs = []\n    self.labels = []\n    self.issue_body_footer = ''\n\n\ndef _to_str_list(values):\n  \"\"\"Convert a list to a list of strs.\"\"\"\n  return [str(value) for value in values]\n\n\nclass IssueTrackerPolicy(object):\n  \"\"\"Represents an issue tracker policy.\"\"\"\n\n  def __init__(self, data):\n    self._data = data\n    if 'status' not in self._data:\n      raise ConfigurationError('Status not set in policies.')\n\n    if 'labels' not in self._data:\n      raise ConfigurationError('Labels not set in policies.')\n\n    for status in EXPECTED_STATUSES:\n      if status not in self._data['status']:\n        raise ConfigurationError(\n            'Expected status {} is not set.'.format(status))\n\n  def status(self, status_type):\n    \"\"\"Get the actual status string for the given type.\"\"\"\n    return self._data['status'][status_type]\n\n  def label(self, label_type):\n    \"\"\"Get the actual label string for the given type.\"\"\"\n    label = self._data['labels'].get(label_type)\n    if label is None:\n      return None\n\n    return str(label)\n\n  def substitution_mapping(self, label):\n    \"\"\"Get an explicit substitution mapping.\"\"\"\n    if 'substitutions' not in self._data:\n      return label\n\n    mapped = self._data['substitutions'].get(label)\n    if not mapped:\n      return label\n\n    return str(mapped)\n\n  @property\n  def deadline_policy_message(self):\n    \"\"\"Get the deadline policy message, if if exists.\"\"\"\n    return self._data.get('deadline_policy_message')\n\n  def get_new_issue_properties(self, is_security, is_crash):\n    \"\"\"Get the properties to apply to a new issue.\"\"\"\n    policy = NewIssuePolicy()\n\n    if 'all' in self._data:\n      self._apply_new_issue_properties(policy, self._data['all'], is_crash)\n\n    if is_security:\n      if 'security' in self._data:\n        self._apply_new_issue_properties(policy, self._data['security'],\n                                         is_crash)\n    else:\n      if 'non_security' in self._data:\n        self._apply_new_issue_properties(policy, self._data['non_security'],\n                                         is_crash)\n\n    return policy\n\n  def _apply_new_issue_properties(self, policy, issue_type, is_crash):\n    \"\"\"Apply issue policies.\"\"\"\n    if not issue_type:\n      return\n\n    if 'status' in issue_type:\n      policy.status = self._data['status'][issue_type['status']]\n\n    if 'ccs' in issue_type:\n      policy.labels.extend(issue_type['ccs'])\n\n    labels = issue_type.get('labels')\n    if labels:\n      policy.labels.extend(_to_str_list(labels))\n\n    issue_body_footer = issue_type.get('issue_body_footer')\n    if issue_body_footer:\n      policy.issue_body_footer = issue_body_footer\n\n    if is_crash:\n      crash_labels = issue_type.get('crash_labels')\n      if crash_labels:\n        policy.labels.extend(_to_str_list(crash_labels))\n    else:\n      non_crash_labels = issue_type.get('non_crash_labels')\n      if non_crash_labels:\n        policy.labels.extend(_to_str_list(non_crash_labels))\n\n  def get_existing_issue_properties(self):\n    \"\"\"Get the properties to apply to a new issue.\"\"\"\n    policy = NewIssuePolicy()\n\n    if 'existing' in self._data:\n      self._apply_new_issue_properties(policy, self._data['existing'], False)\n\n    return policy\n\n\ndef get(project_name):\n  \"\"\"Get policy.\"\"\"\n  issue_tracker_config = local_config.IssueTrackerConfig()\n  project_config = issue_tracker_config.get(project_name)\n  if not project_config:\n    raise ConfigurationError(\n        'Issue tracker for {} does not exist'.format(project_name))\n\n  if not 'policies' in project_config:\n    raise ConfigurationError(\n        'Policies for {} do not exist'.format(project_name))\n\n  return IssueTrackerPolicy(project_config['policies'])\n\n\ndef get_empty():\n  \"\"\"Get an empty policy.\"\"\"\n  return IssueTrackerPolicy({\n      'status': {\n          'assigned': 'unused',\n          'duplicate': 'unused',\n          'wontfix': 'unused',\n          'fixed': 'unused',\n          'verified': 'unused',\n          'new': 'unused',\n      },\n      'labels': {},\n  })\n", "path": "src/appengine/libs/issue_management/issue_tracker_policy.py"}]}