prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Broken link in the GNN Cheat sheet
  ### 📚 Describe the documentation issue
  
  In the cheatsheet [https://pytorch-geometric.readthedocs.io/en/latest/cheatsheet/gnn_cheatsheet.html](https://pytorch-geometric.readthedocs.io/en/latest/cheatsheet/gnn_cheatsheet.html). The paper link for SimpleConv points to a non-existant page. There should not be invalid links on the page.  
  
  [SimpleConv](https://pytorch-geometric.readthedocs.io/en/latest/generated/torch_geometric.nn.conv.SimpleConv.html#torch_geometric.nn.conv.SimpleConv) ([Paper](https://pytorch-geometric.readthedocs.io/en/latest/cheatsheet/None))
  
  ### Suggest a potential alternative/fix
  
  
  I see the code does
  
  ```
      not torch_geometric.nn.conv.utils.processes_point_clouds(cls) %}
      * - :class:`~torch_geometric.nn.conv.{{ cls }}` (`Paper <{{ torch_geometric.nn.conv.utils.paper_link(cls) }}>`__)
        - {% if torch_geometric.nn.conv.utils.supports_sparse_tensor(cls) %}✓{% endif %}
        - {% if 
  ```
  
  If there is a valid appropriate paper - then we should point to that; if not then I suggest having a new document in this repository as the target for this link. The document should describe what SimpleConv does and why there is not paper for it; I assume because it is a very simple example.  
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `torch_geometric/datasets/utils/cheatsheet.py`
  Content:
  ```
  1 import importlib
  2 import inspect
  3 import re
  4 from typing import Any, List, Optional
  5 
  6 
  7 def paper_link(cls: str) -> str:
  8     cls = importlib.import_module('torch_geometric.datasets').__dict__[cls]
  9     match = re.search('<.+?>', inspect.getdoc(cls), flags=re.DOTALL)
  10     return None if match is None else match.group().replace('\n', ' ')[1:-1]
  11 
  12 
  13 def get_stats_table(cls: str) -> str:
  14     cls = importlib.import_module('torch_geometric.datasets').__dict__[cls]
  15     match = re.search(r'\*\*STATS:\*\*\n.*$', inspect.getdoc(cls),
  16                       flags=re.DOTALL)
  17     return '' if match is None else match.group()
  18 
  19 
  20 def has_stats(cls: str) -> bool:
  21     return len(get_stats_table(cls)) > 0
  22 
  23 
  24 def get_type(cls: str) -> str:
  25     return 'Edge' if '-' in cls else 'Node'
  26 
  27 
  28 def get_stat(cls: str, name: str, child: Optional[str] = None,
  29              default: Any = None) -> str:
  30     if child is None and len(get_children(cls)) > 0:
  31         return ''
  32 
  33     stats_table = get_stats_table(cls)
  34 
  35     if len(stats_table) > 0:
  36         stats_table = '\n'.join(stats_table.split('\n')[2:])
  37 
  38     match = re.search(f'^.*- {name}', stats_table, flags=re.DOTALL)
  39     if match is None:
  40         return default
  41 
  42     column = match.group().count(' -')
  43 
  44     if child is not None:
  45         child = child.replace('(', r'\(').replace(')', r'\)')
  46         match = re.search(f'[*] - {child}\n.*$', stats_table, flags=re.DOTALL)
  47         stats_row = match.group()
  48     else:
  49         stats_row = '*' + stats_table.split('*')[2]
  50 
  51     return stats_row.split(' -')[column].split('\n')[0].strip()
  52 
  53 
  54 def get_children(cls: str) -> List[str]:
  55     matches = re.findall('[*] -.*', get_stats_table(cls))
  56     return [match[4:] for match in matches[1:]] if len(matches) > 2 else []
  57
  ```
  
  Path: `torch_geometric/nn/conv/utils/cheatsheet.py`
  Content:
  ```
  1 import importlib
  2 import inspect
  3 import re
  4 
  5 
  6 def paper_title(cls: str) -> str:
  7     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
  8     match = re.search('`\".+?\"', inspect.getdoc(cls), flags=re.DOTALL)
  9     return None if match is None else match.group().replace('\n', ' ')[2:-1]
  10 
  11 
  12 def paper_link(cls: str) -> str:
  13     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
  14     match = re.search('<.+?>', inspect.getdoc(cls), flags=re.DOTALL)
  15     return None if match is None else match.group().replace('\n', ' ')[1:-1]
  16 
  17 
  18 def supports_sparse_tensor(cls: str) -> bool:
  19     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
  20     signature = inspect.signature(cls.forward)
  21     return 'SparseTensor' in str(signature)
  22 
  23 
  24 def supports_edge_weights(cls: str) -> bool:
  25     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
  26     signature = inspect.signature(cls.forward)
  27     return 'edge_weight' in str(signature)
  28 
  29 
  30 def supports_edge_features(cls: str) -> bool:
  31     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
  32     signature = inspect.signature(cls.forward)
  33     return 'edge_attr' in str(signature)
  34 
  35 
  36 def supports_bipartite_graphs(cls: str) -> bool:
  37     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
  38     signature = inspect.signature(cls.forward)
  39     return 'Union[torch.Tensor, Tuple[torch.Tensor' in str(signature)
  40 
  41 
  42 def supports_static_graphs(cls: str) -> bool:
  43     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
  44     return 'node_dim=' not in inspect.getsource(cls.__init__)
  45 
  46 
  47 def supports_lazy_initialization(cls: str) -> bool:
  48     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
  49     doc = re.sub(' +', ' ', inspect.getdoc(cls).replace('\n', ' '))
  50     match = re.search('or :obj:`-1` to derive the size from the first', doc)
  51     return match is not None
  52 
  53 
  54 def processes_heterogeneous_graphs(cls: str) -> bool:
  55     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
  56     signature = inspect.signature(cls.forward)
  57     return 'edge_index_dict' in str(signature) or 'edge_type' in str(signature)
  58 
  59 
  60 def processes_hypergraphs(cls: str) -> bool:
  61     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
  62     signature = inspect.signature(cls.forward)
  63     return 'hyperedge_index' in str(signature)
  64 
  65 
  66 def processes_point_clouds(cls: str) -> bool:
  67     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
  68     signature = inspect.signature(cls.forward)
  69     return (('edge_index' not in str(signature)
  70              and 'csc' not in str(signature)) or 'pos' in str(signature))
  71
  ```
  --- 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/torch_geometric/datasets/utils/cheatsheet.py b/torch_geometric/datasets/utils/cheatsheet.py
  --- a/torch_geometric/datasets/utils/cheatsheet.py
  +++ b/torch_geometric/datasets/utils/cheatsheet.py
  @@ -4,7 +4,7 @@
   from typing import Any, List, Optional
   
   
  -def paper_link(cls: str) -> str:
  +def paper_link(cls: str) -> Optional[str]:
       cls = importlib.import_module('torch_geometric.datasets').__dict__[cls]
       match = re.search('<.+?>', inspect.getdoc(cls), flags=re.DOTALL)
       return None if match is None else match.group().replace('\n', ' ')[1:-1]
  diff --git a/torch_geometric/nn/conv/utils/cheatsheet.py b/torch_geometric/nn/conv/utils/cheatsheet.py
  --- a/torch_geometric/nn/conv/utils/cheatsheet.py
  +++ b/torch_geometric/nn/conv/utils/cheatsheet.py
  @@ -1,15 +1,16 @@
   import importlib
   import inspect
   import re
  +from typing import Optional
   
   
  -def paper_title(cls: str) -> str:
  +def paper_title(cls: str) -> Optional[str]:
       cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
       match = re.search('`\".+?\"', inspect.getdoc(cls), flags=re.DOTALL)
       return None if match is None else match.group().replace('\n', ' ')[2:-1]
   
   
  -def paper_link(cls: str) -> str:
  +def paper_link(cls: str) -> Optional[str]:
       cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]
       match = re.search('<.+?>', inspect.getdoc(cls), flags=re.DOTALL)
       return None if match is None else match.group().replace('\n', ' ')[1:-1]
  
verification_info: {"golden_diff": "diff --git a/torch_geometric/datasets/utils/cheatsheet.py b/torch_geometric/datasets/utils/cheatsheet.py\n--- a/torch_geometric/datasets/utils/cheatsheet.py\n+++ b/torch_geometric/datasets/utils/cheatsheet.py\n@@ -4,7 +4,7 @@\n from typing import Any, List, Optional\n \n \n-def paper_link(cls: str) -> str:\n+def paper_link(cls: str) -> Optional[str]:\n     cls = importlib.import_module('torch_geometric.datasets').__dict__[cls]\n     match = re.search('<.+?>', inspect.getdoc(cls), flags=re.DOTALL)\n     return None if match is None else match.group().replace('\\n', ' ')[1:-1]\ndiff --git a/torch_geometric/nn/conv/utils/cheatsheet.py b/torch_geometric/nn/conv/utils/cheatsheet.py\n--- a/torch_geometric/nn/conv/utils/cheatsheet.py\n+++ b/torch_geometric/nn/conv/utils/cheatsheet.py\n@@ -1,15 +1,16 @@\n import importlib\n import inspect\n import re\n+from typing import Optional\n \n \n-def paper_title(cls: str) -> str:\n+def paper_title(cls: str) -> Optional[str]:\n     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n     match = re.search('`\\\".+?\\\"', inspect.getdoc(cls), flags=re.DOTALL)\n     return None if match is None else match.group().replace('\\n', ' ')[2:-1]\n \n \n-def paper_link(cls: str) -> str:\n+def paper_link(cls: str) -> Optional[str]:\n     cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n     match = re.search('<.+?>', inspect.getdoc(cls), flags=re.DOTALL)\n     return None if match is None else match.group().replace('\\n', ' ')[1:-1]\n", "issue": "Broken link in the GNN Cheat sheet\n### \ud83d\udcda Describe the documentation issue\r\n\r\nIn the cheatsheet [https://pytorch-geometric.readthedocs.io/en/latest/cheatsheet/gnn_cheatsheet.html](https://pytorch-geometric.readthedocs.io/en/latest/cheatsheet/gnn_cheatsheet.html). The paper link for SimpleConv points to a non-existant page. There should not be invalid links on the page.  \r\n\r\n[SimpleConv](https://pytorch-geometric.readthedocs.io/en/latest/generated/torch_geometric.nn.conv.SimpleConv.html#torch_geometric.nn.conv.SimpleConv) ([Paper](https://pytorch-geometric.readthedocs.io/en/latest/cheatsheet/None))\r\n\r\n### Suggest a potential alternative/fix\r\n\r\n\r\nI see the code does\r\n\r\n```\r\n    not torch_geometric.nn.conv.utils.processes_point_clouds(cls) %}\r\n    * - :class:`~torch_geometric.nn.conv.{{ cls }}` (`Paper <{{ torch_geometric.nn.conv.utils.paper_link(cls) }}>`__)\r\n      - {% if torch_geometric.nn.conv.utils.supports_sparse_tensor(cls) %}\u2713{% endif %}\r\n      - {% if \r\n```\r\n\r\nIf there is a valid appropriate paper - then we should point to that; if not then I suggest having a new document in this repository as the target for this link. The document should describe what SimpleConv does and why there is not paper for it; I assume because it is a very simple example.  \r\n\r\n\n", "before_files": [{"content": "import importlib\nimport inspect\nimport re\nfrom typing import Any, List, Optional\n\n\ndef paper_link(cls: str) -> str:\n    cls = importlib.import_module('torch_geometric.datasets').__dict__[cls]\n    match = re.search('<.+?>', inspect.getdoc(cls), flags=re.DOTALL)\n    return None if match is None else match.group().replace('\\n', ' ')[1:-1]\n\n\ndef get_stats_table(cls: str) -> str:\n    cls = importlib.import_module('torch_geometric.datasets').__dict__[cls]\n    match = re.search(r'\\*\\*STATS:\\*\\*\\n.*$', inspect.getdoc(cls),\n                      flags=re.DOTALL)\n    return '' if match is None else match.group()\n\n\ndef has_stats(cls: str) -> bool:\n    return len(get_stats_table(cls)) > 0\n\n\ndef get_type(cls: str) -> str:\n    return 'Edge' if '-' in cls else 'Node'\n\n\ndef get_stat(cls: str, name: str, child: Optional[str] = None,\n             default: Any = None) -> str:\n    if child is None and len(get_children(cls)) > 0:\n        return ''\n\n    stats_table = get_stats_table(cls)\n\n    if len(stats_table) > 0:\n        stats_table = '\\n'.join(stats_table.split('\\n')[2:])\n\n    match = re.search(f'^.*- {name}', stats_table, flags=re.DOTALL)\n    if match is None:\n        return default\n\n    column = match.group().count(' -')\n\n    if child is not None:\n        child = child.replace('(', r'\\(').replace(')', r'\\)')\n        match = re.search(f'[*] - {child}\\n.*$', stats_table, flags=re.DOTALL)\n        stats_row = match.group()\n    else:\n        stats_row = '*' + stats_table.split('*')[2]\n\n    return stats_row.split(' -')[column].split('\\n')[0].strip()\n\n\ndef get_children(cls: str) -> List[str]:\n    matches = re.findall('[*] -.*', get_stats_table(cls))\n    return [match[4:] for match in matches[1:]] if len(matches) > 2 else []\n", "path": "torch_geometric/datasets/utils/cheatsheet.py"}, {"content": "import importlib\nimport inspect\nimport re\n\n\ndef paper_title(cls: str) -> str:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    match = re.search('`\\\".+?\\\"', inspect.getdoc(cls), flags=re.DOTALL)\n    return None if match is None else match.group().replace('\\n', ' ')[2:-1]\n\n\ndef paper_link(cls: str) -> str:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    match = re.search('<.+?>', inspect.getdoc(cls), flags=re.DOTALL)\n    return None if match is None else match.group().replace('\\n', ' ')[1:-1]\n\n\ndef supports_sparse_tensor(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'SparseTensor' in str(signature)\n\n\ndef supports_edge_weights(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'edge_weight' in str(signature)\n\n\ndef supports_edge_features(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'edge_attr' in str(signature)\n\n\ndef supports_bipartite_graphs(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'Union[torch.Tensor, Tuple[torch.Tensor' in str(signature)\n\n\ndef supports_static_graphs(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    return 'node_dim=' not in inspect.getsource(cls.__init__)\n\n\ndef supports_lazy_initialization(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    doc = re.sub(' +', ' ', inspect.getdoc(cls).replace('\\n', ' '))\n    match = re.search('or :obj:`-1` to derive the size from the first', doc)\n    return match is not None\n\n\ndef processes_heterogeneous_graphs(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'edge_index_dict' in str(signature) or 'edge_type' in str(signature)\n\n\ndef processes_hypergraphs(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'hyperedge_index' in str(signature)\n\n\ndef processes_point_clouds(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return (('edge_index' not in str(signature)\n             and 'csc' not in str(signature)) or 'pos' in str(signature))\n", "path": "torch_geometric/nn/conv/utils/cheatsheet.py"}], "after_files": [{"content": "import importlib\nimport inspect\nimport re\nfrom typing import Any, List, Optional\n\n\ndef paper_link(cls: str) -> Optional[str]:\n    cls = importlib.import_module('torch_geometric.datasets').__dict__[cls]\n    match = re.search('<.+?>', inspect.getdoc(cls), flags=re.DOTALL)\n    return None if match is None else match.group().replace('\\n', ' ')[1:-1]\n\n\ndef get_stats_table(cls: str) -> str:\n    cls = importlib.import_module('torch_geometric.datasets').__dict__[cls]\n    match = re.search(r'\\*\\*STATS:\\*\\*\\n.*$', inspect.getdoc(cls),\n                      flags=re.DOTALL)\n    return '' if match is None else match.group()\n\n\ndef has_stats(cls: str) -> bool:\n    return len(get_stats_table(cls)) > 0\n\n\ndef get_type(cls: str) -> str:\n    return 'Edge' if '-' in cls else 'Node'\n\n\ndef get_stat(cls: str, name: str, child: Optional[str] = None,\n             default: Any = None) -> str:\n    if child is None and len(get_children(cls)) > 0:\n        return ''\n\n    stats_table = get_stats_table(cls)\n\n    if len(stats_table) > 0:\n        stats_table = '\\n'.join(stats_table.split('\\n')[2:])\n\n    match = re.search(f'^.*- {name}', stats_table, flags=re.DOTALL)\n    if match is None:\n        return default\n\n    column = match.group().count(' -')\n\n    if child is not None:\n        child = child.replace('(', r'\\(').replace(')', r'\\)')\n        match = re.search(f'[*] - {child}\\n.*$', stats_table, flags=re.DOTALL)\n        stats_row = match.group()\n    else:\n        stats_row = '*' + stats_table.split('*')[2]\n\n    return stats_row.split(' -')[column].split('\\n')[0].strip()\n\n\ndef get_children(cls: str) -> List[str]:\n    matches = re.findall('[*] -.*', get_stats_table(cls))\n    return [match[4:] for match in matches[1:]] if len(matches) > 2 else []\n", "path": "torch_geometric/datasets/utils/cheatsheet.py"}, {"content": "import importlib\nimport inspect\nimport re\nfrom typing import Optional\n\n\ndef paper_title(cls: str) -> Optional[str]:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    match = re.search('`\\\".+?\\\"', inspect.getdoc(cls), flags=re.DOTALL)\n    return None if match is None else match.group().replace('\\n', ' ')[2:-1]\n\n\ndef paper_link(cls: str) -> Optional[str]:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    match = re.search('<.+?>', inspect.getdoc(cls), flags=re.DOTALL)\n    return None if match is None else match.group().replace('\\n', ' ')[1:-1]\n\n\ndef supports_sparse_tensor(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'SparseTensor' in str(signature)\n\n\ndef supports_edge_weights(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'edge_weight' in str(signature)\n\n\ndef supports_edge_features(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'edge_attr' in str(signature)\n\n\ndef supports_bipartite_graphs(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'Union[torch.Tensor, Tuple[torch.Tensor' in str(signature)\n\n\ndef supports_static_graphs(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    return 'node_dim=' not in inspect.getsource(cls.__init__)\n\n\ndef supports_lazy_initialization(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    doc = re.sub(' +', ' ', inspect.getdoc(cls).replace('\\n', ' '))\n    match = re.search('or :obj:`-1` to derive the size from the first', doc)\n    return match is not None\n\n\ndef processes_heterogeneous_graphs(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'edge_index_dict' in str(signature) or 'edge_type' in str(signature)\n\n\ndef processes_hypergraphs(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return 'hyperedge_index' in str(signature)\n\n\ndef processes_point_clouds(cls: str) -> bool:\n    cls = importlib.import_module('torch_geometric.nn.conv').__dict__[cls]\n    signature = inspect.signature(cls.forward)\n    return (('edge_index' not in str(signature)\n             and 'csc' not in str(signature)) or 'pos' in str(signature))\n", "path": "torch_geometric/nn/conv/utils/cheatsheet.py"}]}