@@ -42,19 +42,29 @@ def enforce_type(
42
42
43
43
def _impl (array , type , highlevel , behavior ):
44
44
layout = ak .to_layout (array )
45
- type_ = (
46
- ak .types .from_datashape (type , highlevel = False )
47
- if isinstance (type , str )
48
- else type
49
- )
45
+
46
+ if isinstance (type , str ):
47
+ type_ = ak .types .from_datashape (type , highlevel = False )
48
+
49
+ def select_parameters (type_ : ak .types .Type , layout : ak .contents .Content ):
50
+ return layout .parameters
51
+
52
+ else :
53
+
54
+ def select_parameters (type_ : ak .types .Type , layout : ak .contents .Content ):
55
+ return type_ .parameters
56
+
57
+ type_ = type
50
58
51
59
def recurse (
52
60
type : ak .types .Type , layout : ak .contents .Content
53
61
) -> ak .contents .Content :
54
62
# Early exit - unknown layouts take the form of the type.
55
63
if layout .is_unknown :
56
64
type_form = ak .forms .from_type (type )
57
- return type_form .length_zero_array ()
65
+ return type_form .length_zero_array (highlevel = False ).copy (
66
+ parameters = select_parameters (type , layout )
67
+ )
58
68
59
69
# If we want to lose the option
60
70
elif layout .is_option and not isinstance (type , ak .types .OptionType ):
@@ -67,11 +77,15 @@ def recurse(
67
77
68
78
# Indexed nodes are invisible to layouts
69
79
elif layout .is_indexed :
70
- return recurse (type , layout .content )
80
+ return recurse (type , layout .content ).copy (
81
+ parameters = select_parameters (type , layout )
82
+ )
71
83
72
84
if isinstance (type , ak .types .NumpyType ):
73
85
assert layout .is_numpy
74
86
87
+ layout = layout .copy (parameters = select_parameters (type , layout ))
88
+
75
89
dtype = primitive_to_dtype (type .primitive )
76
90
if np .issubdtype (layout .dtype , dtype ):
77
91
return layout
@@ -88,9 +102,15 @@ def recurse(
88
102
layout .is_numpy and layout .inner_shape [0 ] == type .size
89
103
):
90
104
layout = layout .to_ListOffsetArray64 (True )
91
- return layout .copy (content = recurse (type .content , layout .content ))
105
+ return layout .copy (
106
+ content = recurse (type .content , layout .content ),
107
+ parameters = select_parameters (type , layout ),
108
+ )
92
109
elif layout .is_list :
93
- return layout .copy (content = recurse (type .content , layout .content ))
110
+ return layout .copy (
111
+ content = recurse (type .content , layout .content ),
112
+ parameters = select_parameters (type , layout ),
113
+ )
94
114
else :
95
115
raise wrap_error (
96
116
AssertionError (f"expected list type, found { type (layout )!r} " )
@@ -105,10 +125,16 @@ def recurse(
105
125
if (layout .is_regular and layout .size == type .size ) or (
106
126
layout .is_numpy and layout .inner_shape [0 ] == type .size
107
127
):
108
- return layout .copy (content = recurse (type .content , layout .content ))
128
+ return layout .copy (
129
+ content = recurse (type .content , layout .content ),
130
+ parameters = select_parameters (type , layout ),
131
+ )
109
132
elif layout .is_list :
110
133
layout = layout .to_RegularArray ()
111
- return layout .copy (content = recurse (type .content , layout .content ))
134
+ return layout .copy (
135
+ content = recurse (type .content , layout .content ),
136
+ parameters = select_parameters (type , layout ),
137
+ )
112
138
else :
113
139
raise wrap_error (
114
140
AssertionError (f"expected list type, found { type (layout )!r} " )
@@ -118,18 +144,27 @@ def recurse(
118
144
assert layout .is_record
119
145
assert layout .fields == type .fields # TODO: do we care about order?
120
146
return layout .copy (
121
- contents = [recurse (x , y ) for x , y in zip (type .contents , layout .contents )]
147
+ contents = [
148
+ recurse (x , y ) for x , y in zip (type .contents , layout .contents )
149
+ ],
150
+ parameters = select_parameters (type , layout ),
122
151
)
123
152
124
153
elif isinstance (type , ak .types .UnionType ):
125
154
assert layout .is_union
126
155
return layout .copy (
127
- contents = [recurse (x , y ) for x , y in zip (type .contents , layout .contents )]
156
+ contents = [
157
+ recurse (x , y ) for x , y in zip (type .contents , layout .contents )
158
+ ],
159
+ parameters = select_parameters (type , layout ),
128
160
)
129
161
130
162
elif isinstance (type , ak .types .OptionType ):
131
163
if layout .is_option :
132
- return layout .copy (content = recurse (type .content , layout .content ))
164
+ return layout .copy (
165
+ content = recurse (type .content , layout .content ),
166
+ parameters = select_parameters (type , layout ),
167
+ )
133
168
else :
134
169
return ak .contents .UnmaskedArray (recurse (type .content , layout ))
135
170
0 commit comments