Repository: onnx/onnx

Issue:
[Feature request] Expose lexical scope context in Python checker
### System information

Latest

### What is the problem that this feature solves?

Currently lexical scope context  is not exposed in Python onnx.checker.

### Alternatives considered

_No response_

### Describe the feature

Follow up of https://github.com/onnx/onnx/pull/4720. Expose lexical scope context in Python onnx.checker. See https://github.com/onnx/onnx/blob/3747442528c820ab8dd41111ef3e9ab1a4da6062/onnx/cpp2py_export.cc#L378

### Will this influence the current api (Y/N)?

Y. Extended parameters will be added.

### Feature Area

checker

### Are you willing to contribute it (Y/N)

Yes

### Notes

_No response_


Discussion:

Resolving patch:
diff --git a/onnx/checker.py b/onnx/checker.py
--- a/onnx/checker.py
+++ b/onnx/checker.py
@@ -15,6 +15,7 @@
     "check_tensor",
     "check_value_info",
     "DEFAULT_CONTEXT",
+    "LEXICAL_SCOPE_CONTEXT",
     "ValidationError",
     "C",
     "MAXIMUM_PROTOBUF",
@@ -39,7 +40,6 @@
     SparseTensorProto,
     TensorProto,
     ValueInfoProto,
-    helper,
 )
 
 # Limitation of single protobuf file is 2GB
@@ -56,6 +56,8 @@
 # TODO: Maybe ONNX-ML should also be defaulted?
 DEFAULT_CONTEXT.opset_imports = {"": onnx.defs.onnx_opset_version()}
 
+LEXICAL_SCOPE_CONTEXT = C.LexicalScopeContext()
+
 
 FuncType = TypeVar("FuncType", bound=Callable[..., Any])
 
@@ -80,36 +82,39 @@ def check_tensor(tensor: TensorProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -
 
 
 def check_attribute(
-    attr: AttributeProto, ctx: C.CheckerContext = DEFAULT_CONTEXT
+    attr: AttributeProto,
+    ctx: C.CheckerContext = DEFAULT_CONTEXT,
+    lex_ctx: C.LexicalScopeContext = LEXICAL_SCOPE_CONTEXT,
 ) -> None:
     _ensure_proto_type(attr, AttributeProto)
-    return C.check_attribute(attr.SerializeToString(), ctx)
+    return C.check_attribute(attr.SerializeToString(), ctx, lex_ctx)
 
 
-def check_node(node: NodeProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -> None:
+def check_node(
+    node: NodeProto,
+    ctx: C.CheckerContext = DEFAULT_CONTEXT,
+    lex_ctx: C.LexicalScopeContext = LEXICAL_SCOPE_CONTEXT,
+) -> None:
     _ensure_proto_type(node, NodeProto)
-    return C.check_node(node.SerializeToString(), ctx)
+    return C.check_node(node.SerializeToString(), ctx, lex_ctx)
 
 
 def check_function(
-    function: FunctionProto, ctx: C.CheckerContext | None = None
+    function: FunctionProto,
+    ctx: C.CheckerContext,
+    lex_ctx: C.LexicalScopeContext,
 ) -> None:
     _ensure_proto_type(function, FunctionProto)
-    if ctx is None:
-        ctx = C.CheckerContext()
-        ctx.ir_version = helper.find_min_ir_version_for(
-            list(function.opset_import), True
-        )
-        function_opset_dic = {}
-        for domain_version in function.opset_import:
-            function_opset_dic[domain_version.domain] = domain_version.version
-        ctx.opset_imports = function_opset_dic
-    C.check_function(function.SerializeToString(), ctx)
+    C.check_function(function.SerializeToString(), ctx, lex_ctx)
 
 
-def check_graph(graph: GraphProto, ctx: C.CheckerContext = DEFAULT_CONTEXT) -> None:
+def check_graph(
+    graph: GraphProto,
+    ctx: C.CheckerContext = DEFAULT_CONTEXT,
+    lex_ctx: C.LexicalScopeContext = LEXICAL_SCOPE_CONTEXT,
+) -> None:
     _ensure_proto_type(graph, GraphProto)
-    return C.check_graph(graph.SerializeToString(), ctx)
+    return C.check_graph(graph.SerializeToString(), ctx, lex_ctx)
 
 
 def check_sparse_tensor(


Test patch:
diff --git a/onnx/test/checker_test.py b/onnx/test/checker_test.py
--- a/onnx/test/checker_test.py
+++ b/onnx/test/checker_test.py
@@ -9,6 +9,7 @@
 import onnx.defs
 import onnx.parser
 from onnx import (
+    IR_VERSION,
     GraphProto,
     SparseTensorProto,
     TensorProto,
@@ -91,15 +92,23 @@ def test_check_function_nested(self) -> None:
             func_nested_identity_add_nodes,
             func_nested_opset_imports,
         )
-        checker.check_function(func_nested_identity_add)
+        ctx = checker.C.CheckerContext()
+        ctx.ir_version = IR_VERSION
+        ctx.opset_imports = {"": 14}
+
+        lex_ctx = checker.C.LexicalScopeContext()
+
+        checker.check_function(func_nested_identity_add, ctx, lex_ctx)
 
     def test_check_graph_ir_version_3(self) -> None:
         ctx = checker.C.CheckerContext()
         ctx.ir_version = 3
         ctx.opset_imports = {"": onnx.defs.onnx_opset_version()}
 
+        lex_ctx = checker.C.LexicalScopeContext()
+
         def check_ir_version_3(g: GraphProto) -> None:
-            checker.check_graph(g, ctx)
+            checker.check_graph(g, ctx, lex_ctx)
 
         node = helper.make_node("Relu", ["X"], ["Y"], name="test")
         graph = helper.make_graph(