Skip to content

Commit 2fe510b

Browse files
authored
Preserve collection metadata in basilisp.walk/walk (#1124)
Fixes #1123
1 parent 20ad65b commit 2fe510b

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
## [Unreleased]
88
### Fixed
99
* Fix a bug where `basilisp test` command fails due to an invalid `argparse` configuration (#1119)
10+
* Fix a bug where `basilisp.walk/walk` (and any functions that depend on it) did not preserve collection metadata (#1123)
11+
* Fix a bug where the private `postwalk` implementation in the reader did not preserve collection metadata (#1123)
1012

1113
## [v0.3.1]
1214
### Added

src/basilisp/lang/reader.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,22 +1116,34 @@ def _walk(form, _, outer_f):
11161116
@_walk.register(IPersistentList)
11171117
@_walk.register(ISeq)
11181118
def _walk_ipersistentlist(form: Union[IPersistentList, ISeq], inner_f, outer_f):
1119-
return outer_f(llist.list(map(inner_f, form)))
1119+
coll = llist.list(map(inner_f, form))
1120+
if isinstance(form, IMeta) and form.meta is not None:
1121+
coll = coll.with_meta(form.meta)
1122+
return outer_f(coll)
11201123

11211124

11221125
@_walk.register(IPersistentVector)
11231126
def _walk_ipersistentvector(form: IPersistentVector, inner_f, outer_f):
1124-
return outer_f(vec.vector(map(inner_f, form)))
1127+
coll = vec.vector(map(inner_f, form))
1128+
if isinstance(form, IMeta) and form.meta is not None:
1129+
coll = coll.with_meta(form.meta)
1130+
return outer_f(coll)
11251131

11261132

11271133
@_walk.register(IPersistentMap)
11281134
def _walk_ipersistentmap(form: IPersistentMap, inner_f, outer_f):
1129-
return outer_f(lmap.hash_map(*chain.from_iterable(map(inner_f, form.seq() or ()))))
1135+
coll = lmap.hash_map(*chain.from_iterable(map(inner_f, form.seq() or ())))
1136+
if isinstance(form, IMeta) and form.meta is not None:
1137+
coll = coll.with_meta(form.meta)
1138+
return outer_f(coll)
11301139

11311140

11321141
@_walk.register(IPersistentSet)
11331142
def _walk_ipersistentset(form: IPersistentSet, inner_f, outer_f):
1134-
return outer_f(lset.set(map(inner_f, form)))
1143+
coll = lset.set(map(inner_f, form))
1144+
if isinstance(form, IMeta) and form.meta is not None:
1145+
coll = coll.with_meta(form.meta)
1146+
return outer_f(coll)
11351147

11361148

11371149
def _postwalk(f, form):

src/basilisp/walk.lpy

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,27 @@
1212
(extend-protocol IWalkable
1313
basilisp.lang.interfaces/IPersistentList
1414
(walk* [this inner outer]
15-
(outer (apply list (map inner this))))
15+
(outer (with-meta (apply list (map inner this)) (meta this))))
1616

1717
basilisp.lang.interfaces/IMapEntry
1818
(walk* [this inner outer]
1919
(outer (map-entry (inner (key this)) (inner (val this)))))
2020

2121
basilisp.lang.interfaces/ISeq
2222
(walk* [this inner outer]
23-
(outer (doall (map inner this))))
23+
(outer (with-meta (doall (map inner this)) (meta this))))
2424

2525
basilisp.lang.interfaces/IPersistentVector
2626
(walk* [this inner outer]
27-
(outer (apply vector (map inner this))))
27+
(outer (with-meta (apply vector (map inner this)) (meta this))))
2828

2929
basilisp.lang.interfaces/IPersistentMap
3030
(walk* [this inner outer]
31-
(outer (apply hash-map (mapcat inner this))))
31+
(outer (with-meta (apply hash-map (mapcat inner this)) (meta this))))
3232

3333
basilisp.lang.interfaces/IPersistentSet
3434
(walk* [this inner outer]
35-
(outer (apply hash-set (map inner this))))
35+
(outer (with-meta (apply hash-set (map inner this)) (meta this))))
3636

3737
basilisp.lang.interfaces/IRecord
3838
(walk* [this inner outer]

0 commit comments

Comments
 (0)