Skip to content

Commit a2c2ab7

Browse files
committed
BUG: fix inconsistent (Atom, Structure) pickle
Make sure first Atom stays contained after un-pickling. Use more delicate copying behavior in `Structure.extend()`.
1 parent b6d9961 commit a2c2ab7

File tree

1 file changed

+32
-13
lines changed

1 file changed

+32
-13
lines changed

src/diffpy/structure/structure.py

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -338,19 +338,38 @@ def insert(self, idx, a, copy=True):
338338
return
339339

340340

341-
def extend(self, atoms, copy=True):
342-
"""Extend Structure by appending copies from a list of atoms.
343-
344-
atoms -- list of Atom instances
345-
copy -- flag for extending with copies of Atom instances.
346-
When False extend with atoms and update their lattice
347-
attributes.
348-
349-
No return value.
341+
def extend(self, atoms, copy=None):
342+
"""Extend Structure with the specified sequence of atoms.
343+
344+
Update the `lattice` attribute of all added atoms.
345+
346+
Parameters
347+
----------
348+
atoms : iterable
349+
The `Atom` instances to be appended to this Structure.
350+
copy : bool, optional
351+
Flag for adding copies of Atom objects.
352+
Make copies when `True`, append `atoms` as are when ``False``.
353+
The default behavior is to make copies when `atoms` are
354+
of `Structure` type or if the new atoms introduce repeated
355+
instances.
350356
"""
351-
adups = map(Atom, atoms) if copy else atoms
357+
adups = (copymod.copy(a) for a in atoms)
358+
if copy is None:
359+
if isinstance(atoms, Structure):
360+
extatoms = adups
361+
else:
362+
memo = set(id(a) for a in self)
363+
newatom = lambda a: (a if id(a) not in memo
364+
else copymod.copy(a))
365+
mark = lambda a: (memo.add(id(a)), a)[-1]
366+
extatoms = (mark(newatom(a)) for a in atoms)
367+
elif copy:
368+
extatoms = adups
369+
else:
370+
extatoms = atoms
352371
setlat = lambda a: (setattr(a, 'lattice', self.lattice), a)[-1]
353-
super(Structure, self).extend(setlat(a) for a in adups)
372+
super(Structure, self).extend(setlat(a) for a in extatoms)
354373
return
355374

356375

@@ -476,7 +495,7 @@ def __iadd__(self, other):
476495
477496
Return self.
478497
'''
479-
self.extend(other)
498+
self.extend(other, copy=True)
480499
return self
481500

482501

@@ -533,7 +552,7 @@ def __imul__(self, n):
533552
if n <= 0:
534553
self[:] = []
535554
else:
536-
self.extend((n - 1) * self.tolist())
555+
self.extend((n - 1) * self.tolist(), copy=True)
537556
return self
538557

539558
# Properties -------------------------------------------------------------

0 commit comments

Comments
 (0)