Skip to content

Commit 580ecd5

Browse files
committed
Add additional text to unit test describing operation and ensure wrapped Raw classes are checked
1 parent 4200a39 commit 580ecd5

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

python/tests/test_wrapper_coverage.py

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,47 +29,60 @@
2929

3030
def missing_exports(internal_obj, wrapped_obj) -> None:
3131
"""
32+
Identify if any of the rust exposted structs or functions do not have wrappers.
33+
3234
Special handling for:
3335
- Raw* classes: Internal implementation details that shouldn't be exposed
3436
- _global_ctx: Internal implementation detail
3537
- __self__, __class__: Python special attributes
3638
"""
37-
# Special case enums - just make sure they exist since dir()
38-
# and other functions get overridden.
39+
# Special case enums - EnumType overrides a some of the internal functions,
40+
# so check all of the values exist and move on
3941
if isinstance(wrapped_obj, EnumType):
42+
expected_values = [v for v in dir(internal_obj) if not v.startswith("__")]
43+
for value in expected_values:
44+
assert value in dir(wrapped_obj)
4045
return
4146

42-
# iterate through all the classes in datafusion._internal
43-
for attr in dir(internal_obj):
47+
for internal_attr_name in dir(internal_obj):
4448
# Skip internal implementation details that shouldn't be exposed in public API
45-
if attr in ["_global_ctx"] or attr.startswith("Raw"):
49+
if internal_attr_name in ["_global_ctx"]:
4650
continue
4751

48-
assert attr in dir(wrapped_obj)
52+
wrapped_attr_name = (
53+
internal_attr_name[3:]
54+
if internal_attr_name.startswith("Raw")
55+
else internal_attr_name
56+
)
57+
assert wrapped_attr_name in dir(wrapped_obj)
4958

50-
internal_attr = getattr(internal_obj, attr)
51-
wrapped_attr = getattr(wrapped_obj, attr)
59+
internal_attr = getattr(internal_obj, internal_attr_name)
60+
wrapped_attr = getattr(wrapped_obj, wrapped_attr_name)
5261

62+
# There are some auto generated attributes that can be None, such as
63+
# __kwdefaults__ and __doc__. As long as these are None on the internal
64+
# object, it's okay to skip them. However if they do exist on the internal
65+
# object they must also exist on the wrapped object.
5366
if internal_attr is not None:
5467
if wrapped_attr is None:
55-
print("Missing attribute: ", attr)
68+
print("Missing attribute: ", internal_attr_name)
5669
assert False
5770

58-
if attr in ["__self__", "__class__"]:
71+
if internal_attr_name in ["__self__", "__class__"]:
5972
continue
6073

61-
# check if the class found in the internal module has a
62-
# wrapper exposed in the public module, datafusion
6374
if isinstance(internal_attr, list):
6475
assert isinstance(wrapped_attr, list)
76+
77+
# We have cases like __all__ that are a list and we want to be certain that
78+
# every value in the list in the internal object is also in the wrapper list
6579
for val in internal_attr:
66-
# Skip Raw* classes as they are internal
6780
if isinstance(val, str) and val.startswith("Raw"):
68-
print("Skipping Raw* class: ", val)
69-
continue
70-
71-
assert val in wrapped_attr
81+
assert val[3:] in wrapped_attr
82+
else:
83+
assert val in wrapped_attr
7284
elif hasattr(internal_attr, "__dict__"):
85+
# Check all submodules recursively
7386
missing_exports(internal_attr, wrapped_attr)
7487

7588

0 commit comments

Comments
 (0)