sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.35k stars 461 forks source link

Attach ignores inheritance of classes spread over distinct files #11925

Open 1659f18b-8e7f-4ace-87e0-ea435f3ce618 opened 12 years ago

1659f18b-8e7f-4ace-87e0-ea435f3ce618 commented 12 years ago

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.

Depends on #11812

CC: @mstreng

Component: misc

Keywords: attach inheritance

Issue created by migration from https://trac.sagemath.org/ticket/11925

mstreng commented 12 years ago
comment:2

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.

mstreng commented 12 years ago

Dependencies: #11812

mstreng commented 12 years ago
comment:3

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.

mstreng commented 12 years ago
comment:4

Workaround: end aap.sage with load noot.sage

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

93749b3a-c0a4-47a7-b178-004ba08b0b97 commented 12 years ago
comment:5

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.