Opened 11 years ago

Last modified 8 years ago

#11925 new defect

Attach ignores inheritance of classes spread over distinct files

Reported by: Johan Bosman Owned by: Jason Grout
Priority: major Milestone: sage-6.4
Component: misc Keywords: attach inheritance
Cc: Marco Streng Merged in:
Authors: Reviewers:
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: #11812 Stopgaps:

Status badges

Description

Suppose one has a file named aap.sage with the following contents:

class Aap(SageObject):
    pass  # Minimum example

and a file named noot.sage that looks like:

class Noot(Aap):
    pass  # Minimum example

Okay, and suppose one attaches both files:

sage: attach aap.sage
sage: attach noot.sage

After working with both files for a while, one changes something in the class Aap and the file aap.sage becomes:

class Aap(SageObject):
    def mies(self):
        print "Wim, zus, Jet!"

Now suppose that, *after* this change, one initializes a Noot object:

sage: noot = Noot()

Then the following gives an error:

sage: noot.mies()
...
AttributeError: 'Noot' object has no attribute 'mies'

If, instead, one re-attaches the files, everything works fine:

sage: attach aap.sage
sage: attach noot.sage
sage: noot = Noot()
sage: noot.mies()
Wim, zus, Jet!

Of course, the whole point of attaching files is that one shouldn't have to re-attach them.

Change History (9)

comment:1 Changed 11 years ago by Johan Bosman

Component: sage-modemisc
Owner: changed from ncalexan to Jason Grout

comment:2 Changed 11 years ago by Marco Streng

Dependencies: #11812

Possible solution: make 2 different modes, one in which only changed files are reloaded (speed), and one in which every file is reloaded as soon as one changes (solves your problem).

The new patch I'm writing at #11812 also introduces different modes: one in which sage files are preparsed through memory and one in which they are preparsed through a file. #11812 will have a big overlap with #11925. This means that maybe I could do both tickets at once, but at the very least one ticket should depend on the other to avoid conflicting patches.

comment:3 in reply to:  2 Changed 11 years ago by Marco Streng

Replying to mstreng:

Possible solution: make 2 different modes, one in which only changed files are reloaded (speed), and one in which every file is reloaded as soon as one changes (solves your problem).

Starting from #11812, this would mean extending sage.misc.preparser.load_attach_mode with an option like "reload_all", and to change sage.misc.preparser.modified_attached_files accordingly.

comment:4 Changed 11 years ago by Marco Streng

Workaround: end aap.sage with load noot.sage

That way, when aap.sage changes and is reloaded, noot.sage is loaded afterwards.

comment:5 Changed 11 years ago by ncalexan

I see Marco has given several work-arounds, which you can probably make work. Be aware that circular dependencies will break the work-around, though.

Various people in the Python community have tried to address the issue, which is that loaded objects, in particular class definitions, do not modify existing objects but rather add new objects to the namespace. Google "reload.py" or "xreload.py" to see attempts to solve this. (Attempts that, in my experience, are worse than the problem.)

The only language/environment I know that hot-patches class definitions satisfactorily is Smalltalk, although I would be willing to bet Erlang and friends could do it too. If you know of others, please tell me -- it is a canonically hard problem and I would love to know more solutions.

comment:6 Changed 9 years ago by Jeroen Demeyer

Milestone: sage-5.11sage-5.12

comment:7 Changed 9 years ago by For batch modifications

Milestone: sage-6.1sage-6.2

comment:8 Changed 9 years ago by For batch modifications

Milestone: sage-6.2sage-6.3

comment:9 Changed 8 years ago by For batch modifications

Milestone: sage-6.3sage-6.4
Note: See TracTickets for help on using tickets.