On Mon, 2007-02-26 at 23:32 +1100, Edward d'Auvergne wrote:
> I've been spending some time thinking about the problem and all the
> required changes. Gary, what do you think about the following
> proposal? The debug, warn, and pedantic flags could be stored in
> self.relax rather than __builtin__ (or could be passed the relevant
> functions, methods, or classes). The RelaxErrors could be changed so
> that they are not nested and individual RelaxErrors could be imported
> by the module requiring the error class (rather than importing *).
> The RelaxWarnings could be similarly modified and shifted into the new
> module 'warnings.py'.
I agree that this looks like the best approach to the problem.
> The issue with this approach is that the debug
> flag is used by the individual RelaxErrors. These objects are normal
> python error objects (subclassed from the Exception class) which are
> called with the following syntax:
>
> if bad:
> raise RelaxError, "This is a bad error."
>
> This instantiates the class, executing the self.__init__() function.
> To get access to the debug flag in this function we could set a global
> 'Debug' flag within the 'error.py' module (which defaults to 0 or
> False). This flag can then be set by the 'Relax' class within the
> file 'relax' when parsing the command line arguments.
We need to do more than just make the debug flag availible, because the
relax exceptions need access to the interpreter in order to save state.
The solution is a simple function in errors.py that drops the Relax
instance into BaseError, then each relax exception will inherit from
there. Something like:
def setupErrors(relax):
mod = sys.modules[__name__]
setattr(mod.BaseError, '_relax', relax)
Alternatively relax could be stored in a variable of the module:
_relax
def setupErrors(relax):
global relax
_relax = relax
The much bigger issue is the question of whether it is appropriate to be
passing the Relax instance about as we do. That, I suspect, is a debate
for another day ...
Chris
>
> I think this simple and logical approach should solve all the issues.
> relax does have a lot of historical baggage - although everything
> works fine there are some parts which can be significantly improved.
>
> Edward
>
>
> P.S. We still need to solve the problem of the relax module search
> path being missing when running individual unit tests.
>
>
> On 2/21/07, Gary S. Thompson <[EMAIL PROTECTED]> wrote:
> > Edward d'Auvergne wrote:
> >
> > > Hi Gary,
> > >
> > >> wellcome back, I hope the search for jobs and fame was fruitful
> > >
> > >
> > > I'll definitely be around in the future. I'm not in a position to
> > > confirm anything though.
> > >
> > >
> > >> I have been trying to get the current unit tests to work from the
> > >> command line e.g. ' ./unit_test_runner.py maths_fns/test_chi2.py'.
> > >> However, most of them fail beacuase the global variable Debug is not
> > >> defined. Chris tells me that this is because debug has been added to the
> > >> python __builtins__ namespace. This points to a couple of questions
> > >>
> > >> 1. why are we playing with __builtins__?
> > >
> > >
> > > A number of relax features are placed into __builtin__, most
> > > significantly the RelaxError and RelaxWarning systems. These mimic
> > > and simply extend the normal python error and warning exception
> > > systems. I did notice that this will be an important issue for stand
> > > alone operation of individual unit tests - the calls to RelaxErrors
> > > will necessarily cause exceptions. As for a solution I don't know the
> > > best way of handling the __builtin__ objects and flags.
> >
> >
> > The first thing to say is that I don't think we should be adding
> > anything to builtins that isn't there already in python(?)
> >
> > >
> > >
> > >> 2. how do we get round this
> > >
> > >
> > > I'm not sure.
> > >
> > >
> > oops ;-)
> >
> > >> as an aside __builtins__ is 'an implementation detail'
> > >> http://docs.python.org/lib/module-builtin.html and its use will prevent
> > >> relax from working on iron python, jython and pypy. So is this use of
> > >> __builtins__ something we need to reconsider...
> > >
> > >
> > > Apart from __builtin__, how else would we have the equivalent of a
> > > 'global' variable (accessible to all parts of the program)? Are there
> > > alternative solutions to using __builtin__ or are there alternative
> > > solutions for getting the __builtin__ relax objects into the unit
> > > tests? I don't see the addition of objects to __builtin__ as a big
> > > implementation issue as __builtin__ exists in all python
> > > implementations
> > > (http://www.jython.org/docs/api/org/python/core/__builtin__.html and
> > > Google picks up the rest of the scattered docs).
> >
> > well that maybe the case for jython now but the fact that the main
> > python documentation says it is implimentation detail (though Chris
> > pointed out to me that this was the per module __builtins__ variable).
> > However, good sources such as the python cookbook also point out that
> > __builtin__ shouldn't be used
> >
> > http://www.oreilly.com/catalog/pythoncook/chapter/ch01.pdf
> > Importing __builtin__ and assigning to its attributes is a trick that
> > basically defines anew built-in object at runtime. All other modules
> > will automatically be able to access these new built-ins without having
> > to do an import. It's not good practice, though, since readers of those
> > modules should not need to know about the strange side effects of other
> > modules in the application. Nevertheless, it's a trick worth knowing
> > about in case you encounter it.
> >
> >
> > In general __builtin__ is just a way of avoiding an import. Now for the
> > relax interpreter that could be avoided just as well by doing an
> > implicit import of a module that defines all globals at the start of the
> > script if you wanted to. For the real hacky programmers dabbling in the
> > source code they would know to do the required imports anyway. e.g. from
> > relax import * would import all globals etc required for relax
> > porgramming...
> >
> > > Wouldn't global
> > > variables have the same issue, being absent, with the stand alone unit
> > > tests?
> >
> >
> > yes, the globals was an aside to the point that if we really multithread
> > python at any time soon ;-) globals will become a no no for things that
> > are not global to all threads
> >
> > > Could an alternative be the creation of a new module which
> > > sets up all the relax __builtin__ objects by importing 'error.py' and
> > > setting dummy values of 'Debug' to zero?
> > >
> >
> > now that is one stratergy we could use. A module that you import and
> > just sets up all of the global/per thread variables required. However, I
> > would still urge against adding anything new to builtins as it is just a
> > method for changing the behaviour of types classes and objects that
> > alread exist and for avoiding pesky import statements for the main
> > python object types. Furthermore having one globals module is also not a
> > good design decisioon as variables start to loose obvious ownership
> > which is what the modules mechannism aims for... (see below)
> >
> >
> > Now to a more philosophical bent. Python global variables are in almost
> > all cases except for __builtin__ __per module__ globals variables. Now I
> > am sure that this is quite a careful design decision made to ensure that
> > the global name space is not poluted and that there is always a clear
> > owner for a variable. Thus in (positivley humble) opinion all globals
> > ought to be global to a module and imported via an import statement. Use
> > of the buitins dictionary to create global global variables is in almost
> > all cases trying to hack roun the philosophical under pinnings of the
> > language and its structures.
> >
> > philosophical bent 2. I am not proposing that we outlaw global variables
> > persay. Just that we will just need to pay special attention. In general
> > it is easier to modify the behaviour of variables within classes (this
> > is what get and set mechanism is for) and overall the most robust long
> > term solution for mutable global and per thread variables is to access
> > them as variables from an instance of a singleton which is global to a
> > module
> >
> > end of philosophical rant!
> >
> >
> > regards
> > gary
> >
> > > Cheers,
> > >
> > > Edward
> > >
> > > .
> > >
> >
> >
> > --
> > -------------------------------------------------------------------
> > Dr Gary Thompson
> > Astbury Centre for Structural Molecular Biology,
> > University of Leeds, Astbury Building,
> > Leeds, LS2 9JT, West-Yorkshire, UK Tel. +44-113-3433024
> > email: [EMAIL PROTECTED] Fax +44-113-2331407
> > -------------------------------------------------------------------
> >
> >
> >
>
> _______________________________________________
> relax (http://nmr-relax.com)
>
> This is the relax-devel mailing list
> [email protected]
>
> To unsubscribe from this list, get a password
> reminder, or change your subscription options,
> visit the list information page at
> https://mail.gna.org/listinfo/relax-devel
>
_______________________________________________
relax (http://nmr-relax.com)
This is the relax-devel mailing list
[email protected]
To unsubscribe from this list, get a password
reminder, or change your subscription options,
visit the list information page at
https://mail.gna.org/listinfo/relax-devel