Repository: gaogaotiantian/coredumpy

Issue:
Reconstruct all the builtin functions so the debugger could be more helpful

Discussion:

Solution patch:
diff --git a/src/coredumpy/types/builtin_types.py b/src/coredumpy/types/builtin_types.py
index 7bdc7cd..83680b5 100644
--- a/src/coredumpy/types/builtin_types.py
+++ b/src/coredumpy/types/builtin_types.py
@@ -1,6 +1,7 @@
 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
 # For details: https://github.com/gaogaotiantian/coredumpy/blob/master/NOTICE.txt
 
+import builtins
 import importlib
 import sys
 import types
@@ -233,10 +234,28 @@ class FrameLocalsProxySupport(DictSupport):
     @classmethod
     def get_type(cls):
         if sys.version_info < (3, 13):
-            raise NotImplementedError
+            raise NotImplementedError()
         return type(sys._getframe().f_locals), "FrameLocalsProxy"
 
     @classmethod
     def dump(cls, obj):
         obj = dict(obj)
         return DictSupport.dump(obj)
+
+
+class BuiltinFunctionSupport(TypeSupportBase):
+    @classmethod
+    def get_type(cls):
+        return types.BuiltinFunctionType, "builtin_function"
+
+    @classmethod
+    def dump(cls, obj: types.BuiltinFunctionType):
+        if obj in builtins.__dict__.values():
+            return {"type": "builtin_function", "value": obj.__qualname__}, None
+        raise NotImplementedError()
+
+    @classmethod
+    def load(cls, data, objects):
+        if data["value"] in builtins.__dict__:
+            return builtins.__dict__[data["value"]], None
+        raise NotImplementedError()


Test patch:
diff --git a/tests/base.py b/tests/base.py
index 53afd19..d056bd3 100644
--- a/tests/base.py
+++ b/tests/base.py
@@ -69,8 +69,10 @@ class TestBase(unittest.TestCase):
         stderr = stderr.decode(errors='backslashreplace')
         return stdout, stderr
 
-    def convert_object(self, obj):
+    def convert_object(self, obj, before_load=None):
         container = PyObjectContainer()
         container.add_object(obj)
+        if before_load:
+            before_load()
         container.load_objects(container.get_objects())
         return container.get_object(str(id(obj)))
diff --git a/tests/test_type_support.py b/tests/test_type_support.py
index 0b89f1b..75fa228 100644
--- a/tests/test_type_support.py
+++ b/tests/test_type_support.py
@@ -5,7 +5,7 @@ import importlib
 import sys
 
 from coredumpy.py_object_container import PyObjectContainer
-from coredumpy.py_object_proxy import _unknown
+from coredumpy.py_object_proxy import _unknown, PyObjectProxy
 from coredumpy.type_support import is_container, TypeSupportBase
 
 from .base import TestBase
@@ -111,6 +111,19 @@ class TestTypeSupport(TestBase):
         proxy = container.get_object(str(id(temp_module_for_test)))
         self.assertEqual(proxy._coredumpy_type, "module")
 
+    def test_builtin_function(self):
+        proxy = self.convert_object(abs)
+        self.assertIs(proxy, abs)
+        proxy = self.convert_object(sys.getsizeof)
+        self.assertIsInstance(proxy, PyObjectProxy)
+        import builtins
+        builtins.__dict__["getsizeof"] = sys.getsizeof
+        proxy = self.convert_object(
+            builtins.getsizeof,  # type: ignore
+            before_load=lambda: builtins.__dict__.pop("getsizeof")
+        )
+        self.assertIsInstance(proxy, PyObjectProxy)
+
     def test_nonexist_attr(self):
         class A:
             def __init__(self, x):