Repository: onnx/onnx

Issue:
Attribute types and default values missing in docs at onnx.ai
# Bug Report

### Describe the bug

The HTML version of the ONNX operator specs at https://onnx.ai/onnx/operators/index.html are missing types and default values for attributes. Compare the [HTML version of Resize](https://onnx.ai/onnx/operators/onnx__Resize.html#resize-18) against the [markdown version](https://github.com/onnx/onnx/blob/main/docs/Operators.md#resize). This is annoying as the HTML version loads faster and is more convenient to browse otherwise.

### Expected behavior

The HTML version of the operator documentation should include types and default values for attributes.


Discussion:

Resolving patch:
diff --git a/docs/docsgen/source/conf.py b/docs/docsgen/source/conf.py
--- a/docs/docsgen/source/conf.py
+++ b/docs/docsgen/source/conf.py
@@ -12,7 +12,7 @@
 # -- Project information -----------------------------------------------------
 
 author = "ONNX"
-copyright = "2022"
+copyright = "2023"
 project = "ONNX"
 release = onnx.__version__
 version = onnx.__version__
@@ -67,24 +67,26 @@
         {"name": "github", "url": "https://github.com/onnx/onnx"},
     ],
     "github_url": "https://github.com/onnx/onnx",
-    "logo": {"image_dark": "onnx-horizontal-white.png"},
     "navbar_center": [],
     "navigation_depth": 5,
     "page_sidebar_items": [],  # default setting is: ["page-toc", "edit-this-page", "sourcelink"],
     "show_nav_level": 0,
     "show_prev_next": True,
     "show_toc_level": 0,
+    # needed for sphinx 6.0
+    "logo": {
+        "text": project,
+        "image_light": html_favicon,
+        "image_dark": "onnx-horizontal-white.png",
+        "alt_text": project,
+    },
 }
 
 intersphinx_mapping = {
-    "https://docs.python.org/": None,
+    "numpy": ("https://numpy.org/doc/stable/", None),
+    "python": (f"https://docs.python.org/{sys.version_info.major}/", None),
+    "scipy": ("https://docs.scipy.org/doc/scipy/", None),
     "torch": ("https://pytorch.org/docs/stable/", None),
-    "numpy": ("https://docs.scipy.org/doc/numpy/", None),
-    "pandas": ("https://pandas.pydata.org/pandas-docs/stable/", None),
-    "python": (f"https://docs.python.org/{sys.version_info.major}", None),
-    "scikit-learn": ("https://scikit-learn.org/stable/", None),
-    "scipy": ("https://docs.scipy.org/doc/scipy/reference", None),
-    "sklearn": ("https://scikit-learn.org/stable/", None),
 }
 
 sphinx_gallery_conf = {
diff --git a/docs/docsgen/source/onnx_sphinx.py b/docs/docsgen/source/onnx_sphinx.py
--- a/docs/docsgen/source/onnx_sphinx.py
+++ b/docs/docsgen/source/onnx_sphinx.py
@@ -131,11 +131,11 @@ def _get_ops_template():  # type: ignore
 
         **Attributes**
 
-        {% for _, attr in sorted(sch.attributes.items()) %}* **{{attr.name}}**{%
-          if attr.required %} (required){% endif %}:
-        {{text_wrap(attr.description, 2)}} {%
-          if attr.default_value %}{{clean_default_value(attr.default_value)}}{%
-          endif %}
+        {% for _, attr in sorted(sch.attributes.items())
+        %}* **{{attr.name}} - {{str(attr.type).split('.')[-1]}}**{%
+          if attr.required %} (required){% endif %} {%
+          if attr.default_value %}{{clean_default_value(attr)}}{%
+          endif %}: {{text_wrap(attr.description, 2)}}
         {% endfor %}
         {% endif %}
         {% if sch.inputs %}
@@ -461,13 +461,33 @@ def build_doc_url(sch):
             doc_url += sch.domain + "."
         return doc_url
 
-    def clean_default_value(value):
-        if isinstance(value, onnx.AttributeProto) and hasattr(value, "default_value"):
-            att = value.default_value
-            if att.type in _attribute_conversion_functions:
-                sval = _attribute_conversion_functions[att.type](att)
-                return f"Default value is ``{sval}``."
-        return ""
+    def format_default_value(value):
+        if isinstance(value, float):
+            formatted = str(np.round(value, 5))
+            # use default formatting, unless too long.
+            if len(formatted) > 10:
+                formatted = f"({value:e})"
+            return formatted
+        if isinstance(value, (bytes, bytearray)):
+            return value.decode("utf-8")
+        return str(value)
+
+    def clean_default_value(attr):
+        if not attr.default_value.name:
+            return ""
+        default_value = onnx.helper.get_attribute_value(attr.default_value)
+        if isinstance(default_value, onnx.AttributeProto) and hasattr(
+            default_value, "default_value"
+        ):
+            if attr.type in _attribute_conversion_functions:
+                sval = _attribute_conversion_functions[attr.type](default_value)
+                return f"(default is ``{sval!r}``)"
+
+        if isinstance(default_value, list):
+            sval = [format_default_value(val) for val in default_value]
+        else:
+            sval = format_default_value(default_value)
+        return f"(default is ``{sval!r}``)"
 
     def text_wrap(text, indent):
         s = " " * indent


Test patch: