Skip to content

Commit bbd4fc4

Browse files
feat: add ak.enforce_type (#2365)
* feat: add `ak.enforce_type` * test: add tests * test: fix argument order * feat: add removal of option! * feat: add option to keep type parameters * refactor: use independent `recurse_` functions * test: add more test cases * feat!: don't permute for recordarrays * feat!: make union conversions stricter * refactor: drop closure abstraction Now that we don't need multi-branch error handling * fix: check metadata in layout equality * fix: allow unions to be unconverted * fix: Python 3.7's sum doesn't accept kwargs * style: pre-commit fixes * feat: don't project indexed types if type matches * misc fixes * feat: convert between strings and char arrays * feat: support changing record lengths * refactor: rename `layout_equal_type` * refactor: change error types * refactor: simplify record handling * fix: recurse into all contents, even if same type! * fix: pack option only for one level * fix: only project option if content type changes * fix: more packing work! * refactor: make all functions private * refactor: rename function * Fix: invert condition * refactor: cleanups * wip: work on documentation * docs: add to toctree * docs: clean-up docstring * docs: small change * fix: correct record (todo: add test with different fields) * fix: regular is also list! * feat: add projection mode * docs: update docstrings * test: add tests for new behavior * docs: fix docstring formatting * docs: fix formatting * docs: small formatting change * docs: small internal notice * fix: support converting 0-length lists to sized regular * refactor: pull out index_nplike * feat: detect projection automatically * refactor: drop single-use helper functions * refactor: simplify branches * test: ensure indexing works properly * docs: clarify when projection vs conversion is used * fix: add note about high level types * test: add scalar test * refactor: move functions around * fix: only operate on part of array used for records * fix: take parameters from `_parameters` * fix: take parameters from `_parameters` * docs: expand on docstrings * fix: catch bug with packing * test: check packing of indexed * fix: preserve field order * test: check _exact_ layouts --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent b9c7c6e commit bbd4fc4

File tree

6 files changed

+2392
-20
lines changed

6 files changed

+2392
-20
lines changed

docs/reference/toctree.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
.. toctree::
149149
:caption: Value and type conversions
150150

151+
generated/ak.enforce_type
151152
generated/ak.nan_to_none
152153
generated/ak.nan_to_num
153154
generated/ak.values_astype

src/awkward/forms/form.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,11 @@ def from_type(type_: ak.types.Type) -> Form:
187187
# Categorical types are reintroduced into forms using metadata
188188
if type_.parameter("__categorical__"):
189189
# Drop categorical placeholder parameter
190-
next_parameters = type_.parameters.copy()
191-
next_parameters.pop("__categorical__")
190+
if type_._parameters is None:
191+
next_parameters = None
192+
else:
193+
next_parameters = type_._parameters.copy()
194+
next_parameters.pop("__categorical__")
192195

193196
if isinstance(type_, ak.types.OptionType):
194197
next_content = from_type(type_.content)
@@ -206,38 +209,38 @@ def from_type(type_: ak.types.Type) -> Form:
206209
)
207210

208211
if isinstance(type_, ak.types.NumpyType):
209-
return ak.forms.NumpyForm(type_.primitive, parameters=type_.parameters)
212+
return ak.forms.NumpyForm(type_.primitive, parameters=type_._parameters)
210213
elif isinstance(type_, ak.types.ListType):
211214
return ak.forms.ListOffsetForm(
212-
"i64", from_type(type_.content), parameters=type_.parameters
215+
"i64", from_type(type_.content), parameters=type_._parameters
213216
)
214217
elif isinstance(type_, ak.types.RegularType):
215218
return ak.forms.RegularForm(
216219
from_type(type_.content),
217220
size=type_.size,
218-
parameters=type_.parameters,
221+
parameters=type_._parameters,
219222
)
220223
elif isinstance(type_, ak.types.OptionType):
221224
return ak.forms.IndexedOptionForm(
222225
"i64",
223226
from_type(type_.content),
224-
parameters=type_.parameters,
227+
parameters=type_._parameters,
225228
)
226229
elif isinstance(type_, ak.types.RecordType):
227230
return ak.forms.RecordForm(
228231
[from_type(c) for c in type_.contents],
229232
type_.fields,
230-
parameters=type_.parameters,
233+
parameters=type_._parameters,
231234
)
232235
elif isinstance(type_, ak.types.UnionType):
233236
return ak.forms.UnionForm(
234237
"i8",
235238
"i64",
236239
[from_type(c) for c in type_.contents],
237-
parameters=type_.parameters,
240+
parameters=type_._parameters,
238241
)
239242
elif isinstance(type_, ak.types.UnknownType):
240-
return ak.forms.EmptyForm(parameters=type_.parameters)
243+
return ak.forms.EmptyForm(parameters=type_._parameters)
241244
elif isinstance(type_, (ak.types.ArrayType, ak.types.ScalarType)):
242245
raise TypeError(
243246
"High-level types (ak.types.ArrayType, ak.types.ScalarType) do not have representations as Awkward forms. "

src/awkward/operations/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from awkward.operations.ak_count_nonzero import *
2323
from awkward.operations.ak_covar import *
2424
from awkward.operations.ak_drop_none import *
25+
from awkward.operations.ak_enforce_type import *
2526
from awkward.operations.ak_fields import *
2627
from awkward.operations.ak_fill_none import *
2728
from awkward.operations.ak_firsts import *

0 commit comments

Comments
 (0)