summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2025-05-09 11:21:53 -0700
committerDylan Baker <dylan@pnwbakers.com>2025-07-19 18:36:40 -0700
commit6e379f0090b606786d540001b4a2de52f57e5e47 (patch)
treece0d303801a5a82b885f4690bbb6004b25258b96
parentc3531971abca0d0987e919f452227b61b392f969 (diff)
downloadmeson-6e379f0090b606786d540001b4a2de52f57e5e47.tar.gz
interpreter: Add a flatten() method to arrays
This allows users to do two things, flatten potentially nested arrays themselves, and, to safely convert types that may be an array to not an array. ```meson x = [meson.get_external_property('may_be_array)].flatten() ``` ```meson x = ['a', ['b', 'c']] assert(x.flatten() == ['a', 'b', 'c']) ```
-rw-r--r--docs/markdown/snippets/array-flatten.md5
-rw-r--r--docs/yaml/elementary/list.yml5
-rw-r--r--mesonbuild/interpreter/primitives/array.py14
-rw-r--r--test cases/common/56 array methods/meson.build9
4 files changed, 32 insertions, 1 deletions
diff --git a/docs/markdown/snippets/array-flatten.md b/docs/markdown/snippets/array-flatten.md
new file mode 100644
index 000000000..eaab19c5b
--- /dev/null
+++ b/docs/markdown/snippets/array-flatten.md
@@ -0,0 +1,5 @@
+## Array `.flatten()` method
+
+Arrays now have a `.flatten()` method, which turns nested arrays into a single
+flat array. This provides the same effect that Meson often does to arrays
+internally, such as when passed to most function arguments.
diff --git a/docs/yaml/elementary/list.yml b/docs/yaml/elementary/list.yml
index 1ffb6d2d3..430f871f9 100644
--- a/docs/yaml/elementary/list.yml
+++ b/docs/yaml/elementary/list.yml
@@ -40,3 +40,8 @@ methods:
- name: length
returns: int
description: Returns the current size of the array / list.
+
+- name: flatten
+ returns: list[any]
+ since: 1.9.0
+ description: Returns a flattened copy of the array, with all nested arrays removed.
diff --git a/mesonbuild/interpreter/primitives/array.py b/mesonbuild/interpreter/primitives/array.py
index ff520a280..d0a244179 100644
--- a/mesonbuild/interpreter/primitives/array.py
+++ b/mesonbuild/interpreter/primitives/array.py
@@ -97,3 +97,17 @@ class ArrayHolder(ObjectHolder[T.List[TYPE_var]], IterableObject):
return self.held_object[other]
except IndexError:
raise InvalidArguments(f'Index {other} out of bounds of array of size {len(self.held_object)}.')
+
+ @noPosargs
+ @noKwargs
+ @FeatureNew('array.flatten', '1.9.0')
+ @InterpreterObject.method('flatten')
+ def flatten_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> TYPE_var:
+ def flatten(obj: TYPE_var) -> T.Iterable[TYPE_var]:
+ if isinstance(obj, list):
+ for o in obj:
+ yield from flatten(o)
+ else:
+ yield obj
+
+ return list(flatten(self.held_object))
diff --git a/test cases/common/56 array methods/meson.build b/test cases/common/56 array methods/meson.build
index e9e4969c7..3707775ec 100644
--- a/test cases/common/56 array methods/meson.build
+++ b/test cases/common/56 array methods/meson.build
@@ -1,4 +1,4 @@
-project('array methods')
+project('array methods', meson_version : '>= 1.9')
empty = []
one = ['abc']
@@ -68,3 +68,10 @@ endif
if not combined.contains('ghi')
error('Combined claims not to contain ghi.')
endif
+
+# test array flattening
+x = ['a', ['b'], [[[[[[['c'], 'd']]], 'e']]]]
+assert(x.length() == 3)
+assert(x.flatten().length() == 5)
+assert(x.flatten() == ['a', 'b', 'c', 'd', 'e'])
+assert(['a', ['b', 'c']].flatten() == ['a', 'b', 'c'])