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: |
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
Component: | sage-mode → misc |
---|---|
Owner: | changed from ncalexan to Jason Grout |
comment:2 follow-up: 3 Changed 11 years ago by
Dependencies: | → #11812 |
---|
comment:3 Changed 11 years ago by
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
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
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
Milestone: | sage-5.11 → sage-5.12 |
---|
comment:7 Changed 9 years ago by
Milestone: | sage-6.1 → sage-6.2 |
---|
comment:8 Changed 9 years ago by
Milestone: | sage-6.2 → sage-6.3 |
---|
comment:9 Changed 8 years ago by
Milestone: | sage-6.3 → sage-6.4 |
---|
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.