Opened 8 years ago

Last modified 8 years ago

#11577 closed defect

save(x,filename) fails for pure Python objects for x if filename contains a dot — at Version 2

Reported by: logix Owned by: was
Priority: minor Milestone: sage-4.7.2
Component: pickling Keywords: .sobj
Cc: Merged in:
Authors: Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Description (last modified by leif)

(The summary actually is not completely accurate - there might be some Python object this works for that I'm not aware of.)

If the filename passed to save() contains a dot, save() assumes that the user doesn't just want to dump the (pickled) object, but instead wants to call the object's save() method. I guess this makes sense in situations like save(g, 'mygraph.png'), but the code should fall back to dumping the pickled version (e.g. via try: ... except AttributeError: ... - suggested via IRC by leif) if the object has no save() method.

leif also suggested checking if the file name extension is known - however I guess that we then should verify this with the object itself (e.g. it wouldn't make sense to save a graphics object to a .wav file) and not statically compare with a list of known extensions.

sage: save((1,1), 'foo2')
sage: save(Matrix(3,3), 'foo.bar3')
sage: save((1,1), 'foo.bar4')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

/tmp/sagedebug/<ipython console> in <module>()

/usr/local/sage/local/lib/python2.6/site-packages/sage/structure/sage_object.so in sage.structure.sage_object.save (sage/structure/sage_object.c:8156)()

AttributeError: 'tuple' object has no attribute 'save'

Here's the culprit:

    # Add '.sobj' if the filename currently has no extension
    if os.path.splitext(filename)[1] == '':
        filename += '.sobj'

    if filename.endswith('.sobj'):
        try:
            obj.save(filename=filename, compress=compress, **kwds)
        except (AttributeError, RuntimeError, TypeError):
            s = cPickle.dumps(obj, protocol=2)
            if compress:
                s = comp.compress(s)
            open(process(filename), 'wb').write(s)
    else:
        # Saving an object to an image file. 
        # XXX This of course fails for plain Python objects:
        obj.save(filename, **kwds)

Change History (2)

comment:1 Changed 8 years ago by logix

  • Description modified (diff)
  • Summary changed from save(x,filename) fails for some types of objects for x if filename contains a dot to save(x,filename) fails for pure Python objects for x if filename contains a dot

comment:2 Changed 8 years ago by leif

  • Component changed from sage-mode to pickling
  • Description modified (diff)
  • Owner changed from ncalexan to was
Note: See TracTickets for help on using tickets.