diff --git a/pyroot/ROOT.py b/pyroot/ROOT.py
index d26294fee7dd7900c616a218818fa8724eff3352..baecc2a9a59d8fb94c1e3f2d64cca62aa71e7038 100755
--- a/pyroot/ROOT.py
+++ b/pyroot/ROOT.py
@@ -1,4 +1,4 @@
-# @(#)root/pyroot:$Name:  $:$Id: ROOT.py,v 1.34 2005/12/07 06:16:16 brun Exp $
+# @(#)root/pyroot:$Name:  $:$Id: ROOT.py,v 1.35 2006/01/03 08:50:19 brun Exp $
 # Author: Wim Lavrijsen (WLavrijsen@lbl.gov)
 # Created: 02/20/03
 # Last: 01/02/06
@@ -78,15 +78,24 @@ if needsGlobal:
    sys.setdlopenflags( dlflags )
 del needsGlobal
 
-## normally, you'll want a ROOT application; fine if one pre-exists from C++
-InitRootApplication()
+## choose interactive-favoured policies
+SetMemoryPolicy( kMemoryHeuristics )
+SetSignalPolicy( kSignalSafe )
+
+## normally, you'll want a ROOT application; don't init any further if
+## one pre-exists from some C++ code somewhere
+c = MakeRootClass( 'PyROOT::TPyROOTApplication' )
+if c.CreatePyROOTApplication():
+   c.InitROOTGlobals()
+   c.InitCINTMessageCallback();
+del c
 
 ## 2.2 has 10 instructions as default, 2.3 has 100 ... make same
 sys.setcheckinterval( 100 )
 
 
 ### data ________________________________________________________________________
-__version__ = '3.3.0'
+__version__ = '4.0.0'
 __author__  = 'Wim Lavrijsen (WLavrijsen@lbl.gov)'
 
 __pseudo__all__ = [ 'gROOT', 'gSystem', 'gInterpreter', 'gPad', 'gVirtualX',
@@ -95,15 +104,9 @@ __all__         = []                         # purposedly empty
 
 _orig_ehook = sys.excepthook
 
-## for setting memory policies; not exported
+## for setting memory and speed policies; not exported
 _memPolicyAPI = [ 'SetMemoryPolicy', 'SetOwnership', 'kMemoryHeuristics', 'kMemoryStrict' ]
-kMemoryHeuristics = 1
-kMemoryStrict     = 2
-
-## speed hack
 _sigPolicyAPI = [ 'SetSignalPolicy', 'kSignalFast', 'kSignalSafe' ]
-kSignalFast = 1
-kSignalSafe = 2
 
 
 ### helpers ---------------------------------------------------------------------
@@ -114,12 +117,6 @@ def split( str ):
    else:
       return str, ''
 
-def safeLookupCall( func, arg ):
-   try:
-      return func( arg )
-   except:
-      return None
-
 
 ### template support ------------------------------------------------------------
 class Template:
@@ -145,7 +142,7 @@ class std:
 ### special cases for gPad, gVirtualX (are C++ macro's) -------------------------
 class _ExpandMacroFunction( object ):
    def __init__( self, klass, func ):
-      c = makeRootClass( klass )
+      c = MakeRootClass( klass )
       self.func = getattr( c, func )
 
    def __getattr__( self, what ):
@@ -242,6 +239,7 @@ def _processRootEvents( controller ):
 class ModuleFacade( object ):
    def __init__( self, module ):
       self.module = module
+      self.libmodule = sys.modules[ 'libPyROOT' ]
 
     # root thread to prevent GUIs from starving
       if not self.module.gROOT.IsBatch():
@@ -268,36 +266,25 @@ class ModuleFacade( object ):
          for name in self.module.__pseudo__all__:
             caller.__dict__[ name ] = getattr( self.module, name )
 
-         sys.modules[ 'libPyROOT' ].gPad = gPad
+         self.libmodule.gPad = gPad
 
        # make the distionary of the calling module ROOT lazy
-         self.module.setRootLazyLookup( caller.__dict__ )
+         self.module.SetRootLazyLookup( caller.__dict__ )
 
        # the actual __all__ is empty
          return self.module.__all__
 
-    # block search for privates
-      if name[0:2] == '__':
-         raise AttributeError( name )
-
-    # attempt to construct "name" as a ROOT class
-      attr = safeLookupCall( makeRootClass, name )
-      if ( attr == None ):
-       # no such class ... try global variable or global enum
-         attr = safeLookupCall( getRootGlobal, name )
-      
-      if ( attr == None ):
-       # no global either ... try through gROOT (e.g. objects from files)
-         attr = gROOT.FindObject( name )
-
-    # if available, cache attribute as appropriate, so we don't come back
-      if attr != None:
-         if type(attr) == PropertyProxy:
-            setattr( self.__class__, name, attr )      # descriptor
-            return getattr( self, name )
-         else:
-            self.__dict__[ name ] = attr               # normal member
-            return attr
+    # lookup into ROOT (which may cause python-side enum/class/global creation)
+      attr = self.libmodule.LookupRootEntity( name )
+
+    # the call above will raise AttributeError as necessary; so if we get here,
+    # attr is valid: cache as appropriate, so we don't come back
+      if type(attr) == PropertyProxy:
+          setattr( self.__class__, name, attr )        # descriptor
+          return getattr( self, name )
+      else:
+          self.__dict__[ name ] = attr                 # normal member
+          return attr
 
     # reaching this point means failure ...
       raise AttributeError( name )
@@ -322,6 +309,7 @@ def cleanup():
       facade.keeppolling = 0
 
  # destroy ROOT module
+   del facade.libmodule
    del sys.modules[ 'libPyROOT' ]
    del facade.module
 
diff --git a/pyroot/inc/LinkDef.h b/pyroot/inc/LinkDef.h
index 064eb7f343be57804e2be78ff72833e572afb27c..485633bcff913d0678f8be482d6fe48315cec40d 100644
--- a/pyroot/inc/LinkDef.h
+++ b/pyroot/inc/LinkDef.h
@@ -6,6 +6,9 @@
 
 #pragma link C++ class TPython;
 #pragma link C++ class TPyReturn;
+
+#pragma link C++ namespace PyROOT;
 #pragma link C++ class PyROOT::TPyException;
+#pragma link C++ class PyROOT::TPyROOTApplication;
 
 #endif
diff --git a/pyroot/inc/TPyException.h b/pyroot/inc/TPyException.h
index 7ae4401b9ddb32309623fc3cb0a544601c0d8191..4109465823e16edcf7292b0829548acdcbf8db20 100644
--- a/pyroot/inc/TPyException.h
+++ b/pyroot/inc/TPyException.h
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: TPyException.h,v 1.2 2005/03/04 18:44:14 brun Exp $
+// @(#)root/pyroot:$Name:  $:$Id: TPyException.h,v 1.3 2005/05/06 10:08:53 brun Exp $
 // Author: Scott Snyder, Apr 2004
 
 #ifndef ROOT_TPyException
@@ -40,14 +40,10 @@
 // Standard
 #include <exception>
 
-// Python
-struct _object;
-typedef _object PyObject;
-
 
 namespace PyROOT {
 
-R__EXTERN PyObject* TPyExceptionMagic;
+R__EXTERN void* TPyExceptionMagic;
 
 class TPyException : public std::exception {
 public:
diff --git a/pyroot/inc/TPyROOTApplication.h b/pyroot/inc/TPyROOTApplication.h
new file mode 100644
index 0000000000000000000000000000000000000000..edfc2184b918aaee4585b9176eb6170dfa4bbf27
--- /dev/null
+++ b/pyroot/inc/TPyROOTApplication.h
@@ -0,0 +1,40 @@
+// Author: Wim Lavrijsen   February 2006
+
+#ifndef ROOT_TPyROOTApplication
+#define ROOT_TPyROOTApplication
+
+//////////////////////////////////////////////////////////////////////////////
+//                                                                          //
+// TPyROOTApplication                                                       //
+//                                                                          //
+// Setup interactive application.                                           //
+//                                                                          //
+//////////////////////////////////////////////////////////////////////////////
+
+
+// ROOT
+#ifndef ROOT_TApplication
+#include "TApplication.h"
+#endif
+
+
+namespace PyROOT {
+
+class TPyROOTApplication : public TApplication {
+public:
+   static Bool_t CreatePyROOTApplication( Bool_t bLoadLibs = kTRUE );
+
+   static Bool_t InitROOTGlobals();
+   static Bool_t InitCINTMessageCallback();
+
+public:
+   TPyROOTApplication(
+      const char* acn, Int_t* argc, char** argv, Bool_t bLoadLibs = kTRUE );
+
+   virtual ~TPyROOTApplication() { }
+   ClassDef(TPyROOTApplication,0)   //Setup interactive application
+};
+
+} // namespace PyROOT
+
+#endif
diff --git a/pyroot/src/ConstructorHolder.cxx b/pyroot/src/ConstructorHolder.cxx
index 08c19176edd9570329d533d065950b915762d4b5..fa95842ecbd4bf3cd650ffd45907e7cfd76d9449 100644
--- a/pyroot/src/ConstructorHolder.cxx
+++ b/pyroot/src/ConstructorHolder.cxx
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: ConstructorHolder.cxx,v 1.6 2005/06/10 14:30:22 brun Exp $
+// @(#)root/pyroot:$Name:  $:$Id: ConstructorHolder.cxx,v 1.7 2005/09/09 05:19:10 brun Exp $
 // Author: Wim Lavrijsen, Apr 2004
 
 // Bindings
@@ -94,8 +94,9 @@ PyObject* PyROOT::TConstructorHolder::operator()( ObjectProxy* self, PyObject* a
       return Py_None;                        // by definition
    }
 
-   PyErr_SetString( PyExc_TypeError, const_cast< char* >(
-      ( std::string( klass->GetName() ) + " constructor failed" ).c_str() ) );
+   if ( ! PyErr_Occurred() )   // should be set, otherwise write a generic error msg
+      PyErr_SetString( PyExc_TypeError, const_cast< char* >(
+         ( std::string( klass->GetName() ) + " constructor failed" ).c_str() ) );
 
 // do not throw an exception, '0' might trigger the overload handler to choose a
 // different constructor, which if all fails will throw an exception
diff --git a/pyroot/src/Converters.cxx b/pyroot/src/Converters.cxx
index 391b1556b3fe6905d8a03bc3c07709153d33641c..9a7c088250fb079d5f2b632fe1858f7ddfa8b164 100644
--- a/pyroot/src/Converters.cxx
+++ b/pyroot/src/Converters.cxx
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: Converters.cxx,v 1.24 2005/12/05 17:40:54 brun Exp $
+// @(#)root/pyroot:$Name:  $:$Id: Converters.cxx,v 1.25 2005/12/07 06:16:16 brun Exp $
 // Author: Wim Lavrijsen, Jan 2005
 
 // Bindings
@@ -75,41 +75,41 @@ Bool_t PyROOT::T##name##Converter::SetArg( PyObject* pyobject, G__CallFunc* func
    if ( PyString_Check( pyobject ) ) {                                        \
       if ( PyString_GET_SIZE( pyobject ) == 1 )                               \
          func->SetArg( (Long_t)PyString_AS_STRING( pyobject )[0] );           \
-      else                                                                    \
+      else {                                                                  \
          PyErr_Format( PyExc_TypeError,                                       \
             #type" expected, got string of size %d", PyString_GET_SIZE( pyobject ) );\
-   } else {                                                                  \
-      Long_t l = PyLong_AsLong( pyobject );                                  \
-      if ( PyErr_Occurred() )                                                \
-         return kFALSE;                                                      \
-      if ( ! ( low <= l && l <= high ) ) {                                   \
+         return kFALSE;                                                       \
+      }                                                                       \
+   } else {                                                                   \
+      Long_t l = PyLong_AsLong( pyobject );                                   \
+      if ( PyErr_Occurred() )                                                 \
+         return kFALSE;                                                       \
+      if ( ! ( low <= l && l <= high ) ) {                                    \
          PyErr_SetString( PyExc_ValueError, "integer to character: value out of range" );\
-         return kFALSE;                                                      \
-      }                                                                      \
-      func->SetArg( l );                                                     \
-   }                                                                         \
-   return kTRUE;                                                             \
-}                                                                            \
-                                                                             \
-PyObject* PyROOT::T##name##Converter::FromMemory( void* address )            \
-{                                                                            \
-   return PyString_FromFormat( "%c", *((type*)address) );                    \
-}                                                                            \
-                                                                             \
-Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address )\
-{                                                                            \
-   const char* buf = PyString_AsString( value );                             \
-   if ( PyErr_Occurred() )                                                   \
-      return kFALSE;                                                         \
-                                                                             \
-   int len = strlen( buf );                                                  \
-   if ( len != 1 ) {                                                         \
+         return kFALSE;                                                       \
+      }                                                                       \
+      func->SetArg( l );                                                      \
+   }                                                                          \
+   return kTRUE;                                                              \
+}                                                                             \
+                                                                              \
+PyObject* PyROOT::T##name##Converter::FromMemory( void* address )             \
+{                                                                             \
+   return PyString_FromFormat( "%c", *((type*)address) );                     \
+}                                                                             \
+                                                                              \
+Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \
+{                                                                             \
+   const char* buf = PyString_AsString( value );                              \
+   if ( PyErr_Occurred() )                                                    \
+      return kFALSE;                                                          \
+   int len = strlen( buf );                                                   \
+   if ( len != 1 ) {                                                          \
       PyErr_Format( PyExc_TypeError, #type" expected, got string of size %d", len );\
-      return kFALSE;                                                         \
-   }                                                                         \
-                                                                             \
-   *((type*)address) = (type)buf[0];                                         \
-   return kTRUE;                                                             \
+      return kFALSE;                                                          \
+   }                                                                          \
+   *((type*)address) = (type)buf[0];                                          \
+   return kTRUE;                                                              \
 }
 
 
@@ -613,6 +613,7 @@ Bool_t PyROOT::T##name##Converter::ToMemory( PyObject* value, void* address ) \
 PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( TString,   TString,     Data )
 PYROOT_IMPLEMENT_STRING_AS_PRIMITIVE_CONVERTER( STLString, std::string, c_str )
 
+static int kaas = 0;
 //____________________________________________________________________________
 Bool_t PyROOT::TRootObjectConverter::SetArg( PyObject* pyobject, G__CallFunc* func )
 {
@@ -638,7 +639,7 @@ Bool_t PyROOT::TRootObjectConverter::SetArg( PyObject* pyobject, G__CallFunc* fu
       G__ClassInfo* clFormalInfo = fClass->GetClassInfo();
       G__ClassInfo* clActualInfo = pyobj->ObjectIsA()->GetClassInfo();
       Long_t offset = 0;
-      if ( clFormalInfo && clActualInfo )
+      if ( clFormalInfo && clActualInfo && clFormalInfo != clActualInfo )
          offset = G__isanybase( clFormalInfo->Tagnum(), clActualInfo->Tagnum(), (Long_t)obj );
 
    // set pointer (may be null) and declare success
diff --git a/pyroot/src/MethodHolder.cxx b/pyroot/src/MethodHolder.cxx
index 55d3b9324c327fc48588706b4997d6afc7c1ec57..646a20ba3a63d52f66bb68363deee460e15e85f7 100644
--- a/pyroot/src/MethodHolder.cxx
+++ b/pyroot/src/MethodHolder.cxx
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: MethodHolder.cxx,v 1.43 2005/12/03 04:00:15 pcanal Exp $
+// @(#)root/pyroot:$Name:  $:$Id: MethodHolder.cxx,v 1.44 2005/12/06 11:47:09 brun Exp $
 // Author: Wim Lavrijsen, Apr 2004
 
 // Bindings
@@ -32,7 +32,7 @@
 #include <string>
 
 
-//- local helpers ------------------------------------------------------------
+//- data and local helpers ---------------------------------------------------
 namespace {
 
 // CINT temp level guard
@@ -96,7 +96,7 @@ inline PyObject* PyROOT::TMethodHolder::CallFast( void* self )
    try {       // C++ try block
       result = fExecutor->Execute( fMethodCall, (void*)((Long_t)self + fOffset) );
    } catch ( TPyException& ) {
-      result = TPyExceptionMagic;
+      result = (PyObject*)TPyExceptionMagic;
    } catch ( std::exception& e ) {
       PyErr_Format( PyExc_Exception, "%s (C++ exception)", e.what() );
       result = 0;
@@ -257,6 +257,31 @@ PyObject* PyROOT::TMethodHolder::GetDocString()
       ( fMethod->Property() & G__BIT_ISSTATIC ) ? "static " : "", fMethod->GetPrototype() );
 }
 
+//____________________________________________________________________________
+Int_t PyROOT::TMethodHolder::GetPriority()
+{
+// Method priorities exist (in lieu of true overloading) there to prevent
+// void* or <unknown>* from usurping otherwise valid calls. TODO: extend this
+// to favour classes that are not bases.
+
+   Int_t priority = 0;
+
+   TIter nextarg( fMethod->GetListOfMethodArgs() );
+   while ( TMethodArg* arg = (TMethodArg*)nextarg() ) {
+      G__TypeInfo ti( arg->GetFullTypeName() );
+
+      if ( ! ti.IsValid() )
+         priority -= 1000;    // class is gibberish
+      else if ( (ti.Property() & (kIsClass|kIsStruct)) && ! ti.IsLoaded() )
+         priority -= 100;     // class is known, but no dictionary available
+      else if ( TClassEdit::CleanType( ti.TrueName(), 1 ) == "void*" )
+         priority -= 10;      // void* shouldn't be too greedy
+
+   }
+
+   return priority;
+}
+
 //____________________________________________________________________________
 Bool_t PyROOT::TMethodHolder::Initialize()
 {
diff --git a/pyroot/src/MethodHolder.h b/pyroot/src/MethodHolder.h
index 2b9f365a7d035fad8ab35a91fa5e88c7eb4ae563..80256a6eb1c3082fe6aa08e72add5e35b94e4622 100644
--- a/pyroot/src/MethodHolder.h
+++ b/pyroot/src/MethodHolder.h
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: MethodHolder.h,v 1.17 2005/10/25 05:13:15 brun Exp $
+// @(#)root/pyroot:$Name:  $:$Id: MethodHolder.h,v 1.18 2005/12/06 11:47:09 brun Exp $
 // Author: Wim Lavrijsen, Apr 2004
 
 #ifndef PYROOT_TMETHODHOLDER_H
@@ -26,7 +26,7 @@ namespace PyROOT {
 /** Python side ROOT method
       @author  WLAV
       @date    05/06/2004
-      @version 2.0
+      @version 2.1
  */
 
    class TExecutor;
@@ -42,6 +42,7 @@ namespace PyROOT {
 
    public:
       virtual PyObject* GetDocString();
+      virtual Int_t GetPriority();
 
    public:
       virtual PyObject* operator()( ObjectProxy* self, PyObject* args, PyObject* kwds );
diff --git a/pyroot/src/MethodProxy.cxx b/pyroot/src/MethodProxy.cxx
index f7ebdcf9662d863e6cb28801e61fbb4929f4e2fc..198e5ce33d1edc77a5a674fa866822d6933fd8f2 100644
--- a/pyroot/src/MethodProxy.cxx
+++ b/pyroot/src/MethodProxy.cxx
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: MethodProxy.cxx,v 1.8 2005/08/10 05:25:41 brun Exp $
+// @(#)root/pyroot:$Name:  $:$Id: MethodProxy.cxx,v 1.9 2005/09/09 05:19:10 brun Exp $
 // Author: Wim Lavrijsen, Jan 2005
 
 // Bindings
@@ -9,6 +9,7 @@
 #include "TPyException.h"
 
 // Standard
+#include <algorithm>
 #include <functional>
 #include <vector>
 #include <algorithm>
@@ -47,6 +48,11 @@ namespace {
       return hash;
    }
 
+// helper to sort on method priority
+   int PriorityCmp( PyCallable* left, PyCallable* right )
+   {
+      return left->GetPriority() > right->GetPriority();
+   }
 
 //= PyROOT method proxy object behaviour =====================================
    PyObject* mp_name( MethodProxy* meth, void* )
@@ -108,7 +114,7 @@ namespace {
          Int_t index = m->second;
          PyObject* result = (*methods[ index ])( meth->fSelf, args, kwds );
 
-         if ( result == TPyExceptionMagic )
+         if ( result == (PyObject*)TPyExceptionMagic )
             return 0;              // exception info was already set
 
          if ( result != 0 )
@@ -119,11 +125,16 @@ namespace {
       }
 
    // ... otherwise loop over all methods and find the one that does not fail
+      if ( ! meth->fMethodInfo->fIsSorted ) {
+         std::stable_sort( methods.begin(), methods.end(), PriorityCmp );
+         meth->fMethodInfo->fIsSorted = kTRUE;
+      }
+
       std::vector< PyError_t > errors;
       for ( Int_t i = 0; i < nMethods; ++i ) {
          PyObject* result = (*methods[i])( meth->fSelf, args, kwds );
 
-         if ( result == TPyExceptionMagic ) {
+         if ( result == (PyObject*)TPyExceptionMagic ) {
             std::for_each( errors.begin(), errors.end(), PyError_t::Clear );
             return 0;              // exception info was already set
          }
@@ -289,4 +300,5 @@ void PyROOT::MethodProxy::Set( const std::string& name, std::vector< PyCallable*
 // set method data
    fMethodInfo->fName = name;
    fMethodInfo->fMethods.swap( methods );
+   fMethodInfo->fIsSorted = kFALSE;
 }
diff --git a/pyroot/src/MethodProxy.h b/pyroot/src/MethodProxy.h
index ee8ec19810a6637aa548df3a88eb36e26d6bddb4..a950e138a7d7f4ea1fcbfeff0b46b4e115b2f85e 100644
--- a/pyroot/src/MethodProxy.h
+++ b/pyroot/src/MethodProxy.h
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: MethodProxy.h,v 1.2 2005/04/13 05:04:50 brun Exp $
+// @(#)root/pyroot:$Name:  $:$Id: MethodProxy.h,v 1.3 2005/09/09 05:19:10 brun Exp $
 // Author: Wim Lavrijsen, Jan 2005
 
 #ifndef PYROOT_METHODPROXY_H
@@ -26,17 +26,18 @@ namespace PyROOT {
 
    class MethodProxy {
    public:
-      typedef std::map< Long_t, Int_t >      DispatchMap_t;
+      typedef std::map< Long_t, Int_t >  DispatchMap_t;
       typedef std::vector< PyCallable* > Methods_t;
 
       struct MethodInfo_t {
-         MethodInfo_t() { fRefCount = new int(1); }
+         MethodInfo_t() : fIsSorted( kFALSE ) { fRefCount = new int(1); }
          ~MethodInfo_t() { delete fRefCount; }
 
          std::string                 fName;
          MethodProxy::DispatchMap_t  fDispatchMap;
          MethodProxy::Methods_t      fMethods;
          std::string                 fDoc;
+         Bool_t                      fIsSorted;
 
          int* fRefCount;
       };
@@ -45,7 +46,8 @@ namespace PyROOT {
       void Set( const std::string& name, std::vector< PyCallable* >& methods );
 
       const std::string& GetName() const { return fMethodInfo->fName; }
-      void AddMethod( PyCallable* pc ) { fMethodInfo->fMethods.push_back( pc ); }
+      void AddMethod( PyCallable* pc ) {
+         fMethodInfo->fIsSorted = kFALSE; fMethodInfo->fMethods.push_back( pc ); }
 
    public:               // public, as the python C-API works with C structs
       PyObject_HEAD
diff --git a/pyroot/src/PyCallable.h b/pyroot/src/PyCallable.h
index 8d885940c57194869e0673b721d664f9120aab8c..074d273ab84d97853796b27027e7208249f6ce69 100644
--- a/pyroot/src/PyCallable.h
+++ b/pyroot/src/PyCallable.h
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: PyCallable.h,v 1.68 2005/01/28 05:45:41 brun Exp $
+// @(#)root/pyroot:$Name:  $:$Id: PyCallable.h,v 1.2 2005/03/04 07:44:11 brun Exp $
 // Author: Wim Lavrijsen, Aug 2004
 
 #ifndef PYROOT_PYCALLABLE_H
@@ -21,6 +21,7 @@ namespace PyROOT {
 
    public:
       virtual PyObject* GetDocString() = 0;
+      virtual Int_t GetPriority() { return 0; }
 
    public:
       virtual PyObject* operator()( ObjectProxy* self, PyObject* args, PyObject* kwds ) = 0;
diff --git a/pyroot/src/Pythonize.cxx b/pyroot/src/Pythonize.cxx
index 694ef7df21c96040d24065aa574b60f50d836280..e19e8f9b532d0c68c5404e43ec1a35145375cca9 100644
--- a/pyroot/src/Pythonize.cxx
+++ b/pyroot/src/Pythonize.cxx
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: Pythonize.cxx,v 1.31 2005/12/03 04:00:15 pcanal Exp $
+// @(#)root/pyroot:$Name:  $:$Id: Pythonize.cxx,v 1.33 2005/12/12 18:06:19 brun Exp $
 // Author: Wim Lavrijsen, Jul 2004
 
 // Bindings
@@ -1300,8 +1300,8 @@ namespace {
             }
          }
 
-         if ( argc == reqNArgs )
-            PyTuple_SET_ITEM( args, reqNArgs, PyInt_FromLong( 0l ) );
+         if ( argc == reqNArgs )             // meaning: use default for last value
+            PyTuple_SET_ITEM( newArgs, reqNArgs, PyInt_FromLong( 0l ) );
 
       // re-run
          PyObject* result = PyObject_CallObject( (PyObject*)method, newArgs );
diff --git a/pyroot/src/RootModule.cxx b/pyroot/src/RootModule.cxx
index e9ca175f52320a446930727cd6947927e20329fe..732348f9e13e7bb854b991b6b60b5480722a9173 100644
--- a/pyroot/src/RootModule.cxx
+++ b/pyroot/src/RootModule.cxx
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: RootModule.cxx,v 1.20 2005/10/25 05:13:15 brun Exp $
+// @(#)root/pyroot:$Name:  $:$Id: RootModule.cxx,v 1.21 2005/11/17 06:26:35 brun Exp $
 // Author: Wim Lavrijsen, Apr 2004
 
 // Bindings
@@ -13,14 +13,7 @@
 
 // ROOT
 #include "TROOT.h"
-#include "TSystem.h"
-#include "TInterpreter.h"
-#include "TApplication.h"
-#include "TBenchmark.h"
-#include "TStyle.h"
-
-// CINT
-#include "Api.h"
+#include "TObject.h"
 
 // Standard
 #include <string>
@@ -35,40 +28,46 @@ namespace {
 
    using namespace PyROOT;
 
-//______________________________________________________________________________
-   class TPyROOTApplication : public TApplication {
-   public:
-      TPyROOTApplication( const char* acn, int* argc, char** argv ) :
-            TApplication( acn, argc, argv )
+//____________________________________________________________________________
+   PyObject* LookupRootEntity( PyObject* pyname, PyObject* args )
+   {
+      if ( ! ( pyname && PyString_CheckExact( pyname ) ) )
+         if ( ! ( args && PyArg_ParseTuple( args, const_cast< char* >( "S" ), &pyname ) ) )
+            return 0;
+
+      std::string name = PyString_AS_STRING( pyname );
+
+   // block search for privates
+      if ( name.size() <= 2 || name.substr( 0, 2 ) != "__" )
       {
-      // follow TRint to minimize differences with CINT
-         ProcessLine( "#include <iostream>", kTRUE );
-         ProcessLine( "#include <_string>",  kTRUE ); // for std::string iostream.
-         ProcessLine( "#include <vector>",   kTRUE ); // needed because they're used within the
-         ProcessLine( "#include <pair>",     kTRUE ); //  core ROOT dicts and CINT won't be able
-                                                      //  to properly unload these files
-
-      // allow the usage of ClassDef and ClassImp in interpreted macros
-         ProcessLine( "#include <RtypesCint.h>", kTRUE );
-
-      // disallow the interpretation of Rtypes.h, TError.h and TGenericClassInfo.h
-         ProcessLine( "#define ROOT_Rtypes 0", kTRUE );
-         ProcessLine( "#define ROOT_TError 0", kTRUE );
-         ProcessLine( "#define ROOT_TGenericClassInfo 0", kTRUE );
-
-      // the following libs are also useful to have, make sure they are loaded...
-         gROOT->LoadClass("TMinuit",     "Minuit");
-         gROOT->LoadClass("TPostScript", "Postscript");
-         gROOT->LoadClass("THtml",       "Html");
-
-      // save current interpreter context
-         gInterpreter->SaveContext();
-         gInterpreter->SaveGlobalsContext();
-
-      // prevent ROOT from exiting python
-         SetReturnFromRun( kTRUE );
+      // 1st attempt: look in myself
+         PyObject* attr = PyObject_GetAttr( gRootModule, pyname );
+         if ( attr != 0 )
+            return attr;
+
+      // 2nd attempt: construct name as a class
+         PyErr_Clear();
+         attr = MakeRootClassFromString( name );
+         if ( attr != 0 )
+            return attr;
+
+      // 3rd attempt: lookup name as global variable
+         PyErr_Clear();
+         attr = GetRootGlobalFromString( name );
+         if ( attr != 0 )
+            return attr;
+
+      // 4th attempt: find existing object (e.g. from file)
+         PyErr_Clear();
+         TObject* object = gROOT->FindObject( name.c_str() );
+         if ( object != 0 )
+            return BindRootObject( object, object->IsA() );
       }
-   };
+
+   // still here? raise attribute error
+      PyErr_Format( PyExc_AttributeError, "%s", name.c_str() );
+      return 0;
+   }
 
 //____________________________________________________________________________
    PyDictEntry* RootLookDictString( PyDictObject* mp, PyObject* key, Long_t hash )
@@ -83,36 +82,11 @@ namespace {
          return ep;
       }
 
-   // filter python private variables (C++ discourages __ as variable start)
-      if ( ! PyString_CheckExact( key ) )
-         return ep;
-
-      std::string strkey = PyString_AS_STRING( key );
-      if ( 2 < strkey.size() && strkey.substr( 0, 2 ) == "__" )
-         return ep;
-
    // all failed, start calling into ROOT
       gDictLookupActive = kTRUE;
 
    // attempt to get ROOT enum/global/class
-      PyObject* val = PyObject_GetAttr( gRootModule, key );
-
-      if ( ! val ) {
-         PyErr_Clear();
-         val = MakeRootClassFromString( strkey );
-      }
-
-      if ( ! val ) {
-         PyErr_Clear();
-         val = GetRootGlobalFromString( strkey );
-      }
-
-      if ( ! val ) {
-         PyErr_Clear();
-         TObject* object = gROOT->FindObject( strkey.c_str() );
-         if ( object != 0 )
-            val = BindRootObject( object, object->IsA() );
-      }
+      PyObject* val = LookupRootEntity( key, 0 );
 
       if ( val != 0 ) {
       // success ...
@@ -134,7 +108,8 @@ namespace {
             ep->me_value = val;
             mp->ma_used++;
          }
-      }
+      } else
+         PyErr_Clear();
 
    // stopped calling into ROOT
       gDictLookupActive = kFALSE;
@@ -142,44 +117,14 @@ namespace {
       return ep;
    }
 
-//____________________________________________________________________________
-   PyObject* InitRootApplication()
-   {
-      if ( ! gApplication ) {
-      // retrieve arg list from python, translate to raw C, pass on
-         PyObject* argl = PySys_GetObject( const_cast< char* >( "argv" ) );
-
-         int argc = argl ? PyList_Size( argl ) : 1;
-         char** argv = new char*[ argc ];
-         for ( int i = 1; i < argc; ++i )
-            argv[ i ] = PyString_AS_STRING( PyList_GET_ITEM( argl, i ) );
-         argv[ 0 ] = Py_GetProgramName();
-
-         gApplication = new TPyROOTApplication( "PyROOT", &argc, argv );
-
-      // CINT message callback (only if loaded from python, i.e. !gApplication)
-         G__set_errmsgcallback( (void*)&PyROOT::Utility::ErrMsgCallback );
-      }
-
-   // setup some more handy ROOT globals
-      if ( ! gBenchmark ) gBenchmark = new TBenchmark();
-      if ( ! gStyle ) gStyle = new TStyle();
-
-      if ( ! gProgName )              // should be set by TApplication
-         gSystem->SetProgname( Py_GetProgramName() );
-
-      Py_INCREF( Py_None );
-      return Py_None;
-   }
-
 //____________________________________________________________________________
    PyObject* SetRootLazyLookup( PyObject*, PyObject* args )
    {
-      PyObject* dict = 0;
+      PyDictObject* dict = 0;
       if ( ! PyArg_ParseTuple( args, const_cast< char* >( "O!" ), &PyDict_Type, &dict ) )
          return 0;
 
-      ((DictLookup_t&)((PyDictObject*)dict)->ma_lookup) = RootLookDictString;
+      ((DictLookup_t&)dict->ma_lookup) = RootLookDictString;
 
       Py_INCREF( Py_None );
       return Py_None;
@@ -377,13 +322,13 @@ namespace {
 
 //- data -----------------------------------------------------------------------
 static PyMethodDef gPyROOTMethods[] = {
-   { (char*) "makeRootClass", (PyCFunction)PyROOT::MakeRootClass,
+   { (char*) "MakeRootClass", (PyCFunction)PyROOT::MakeRootClass,
+     METH_VARARGS, (char*) "PyROOT internal function" },
+   { (char*) "GetRootGlobal", (PyCFunction)PyROOT::GetRootGlobal,
      METH_VARARGS, (char*) "PyROOT internal function" },
-   { (char*) "getRootGlobal", (PyCFunction)PyROOT::GetRootGlobal,
+   { (char*) "LookupRootEntity", (PyCFunction)LookupRootEntity,
      METH_VARARGS, (char*) "PyROOT internal function" },
-   { (char*) "InitRootApplication", (PyCFunction)InitRootApplication,
-     METH_NOARGS,  (char*) "PyROOT internal function" },
-   { (char*) "setRootLazyLookup", (PyCFunction)SetRootLazyLookup,
+   { (char*) "SetRootLazyLookup", (PyCFunction)SetRootLazyLookup,
      METH_VARARGS, (char*) "PyROOT internal function" },
    { (char*) "MakeRootTemplateClass", (PyCFunction)MakeRootTemplateClass,
      METH_VARARGS, (char*) "PyROOT internal function" },
@@ -433,6 +378,12 @@ extern "C" void initlibPyROOT()
    if ( ! Utility::InitProxy( gRootModule, &PropertyProxy_Type, "PropertyProxy" ) )
       return;
 
+// policy labels
+   PyModule_AddObject( gRootModule, (char*)"kMemoryHeuristics", PyInt_FromLong( 1l ) );
+   PyModule_AddObject( gRootModule, (char*)"kMemoryStrict",     PyInt_FromLong( 2l ) );
+   PyModule_AddObject( gRootModule, (char*)"kSignalFast",       PyInt_FromLong( 1l ) );
+   PyModule_AddObject( gRootModule, (char*)"kSignalSafe",       PyInt_FromLong( 2l ) );
+
 // setup ROOT
    PyROOT::InitRoot();
 
diff --git a/pyroot/src/TPyException.cxx b/pyroot/src/TPyException.cxx
index 6927763469d098bfd99d26e066d1085db77f3e06..dccb38d17a1e49501068455f8ba557063149d602 100644
--- a/pyroot/src/TPyException.cxx
+++ b/pyroot/src/TPyException.cxx
@@ -1,4 +1,4 @@
-// @(#)root/pyroot:$Name:  $:$Id: TPyException.cxx,v 1.1 2005/03/04 07:44:11 brun Exp $
+// @(#)root/pyroot:$Name:  $:$Id: TPyException.cxx,v 1.2 2005/05/06 10:08:53 brun Exp $
 // Author: Scott Snyder, Apr 2004
 
 // Bindings
@@ -21,7 +21,7 @@
 
 //- data ---------------------------------------------------------------------
 ClassImp(PyROOT::TPyException)
-PyObject* PyROOT::TPyExceptionMagic = (PyObject*)-1;
+void* PyROOT::TPyExceptionMagic = (PyObject*)-1;
 
 
 //- constructors/destructor --------------------------------------------------
diff --git a/pyroot/src/TPyROOTApplication.cxx b/pyroot/src/TPyROOTApplication.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..80db5268cd44f653ebbcdab21d2d689aec82fde6
--- /dev/null
+++ b/pyroot/src/TPyROOTApplication.cxx
@@ -0,0 +1,125 @@
+// Author: Wim Lavrijsen, February 2006
+
+// Bindings
+#include "PyROOT.h"
+#include "TPyROOTApplication.h"
+#include "Utility.h"
+
+// ROOT
+#include "TROOT.h"
+#include "TInterpreter.h"
+#include "TSystem.h"
+#include "TBenchmark.h"
+#include "TStyle.h"
+
+// CINT
+#include "Api.h"
+
+
+//______________________________________________________________________________
+//                        Setup interactive application
+//                        =============================
+//
+// The TPyROOTApplication sets up the nuts and bolts for interactive ROOT use
+// from python, closely following TRint. Note that not everything is done here,
+// some bits (such as e.g. the use of exception hook for shell escapes) are more
+// easily done in python and you'll thus find them ROOT.py
+//
+// The intended use of this class is from python only. It is used by default in
+// ROOT.py, so if you do not want to have a TApplication derived object created
+// for you, you'll need to load libPyROOT.so instead.
+//
+// The static InitXYZ functions are used in conjunction with TPyROOTApplication
+// in ROOT.py, but they can be used independently.
+
+
+//- data ---------------------------------------------------------------------
+ClassImp(PyROOT::TPyROOTApplication)
+
+
+//- constructors/destructor --------------------------------------------------
+PyROOT::TPyROOTApplication::TPyROOTApplication(
+   const char* acn, int* argc, char** argv, bool bLoadLibs ) :
+      TApplication( acn, argc, argv )
+{
+// Create a TApplication derived for use with interactive ROOT from python. A
+// set of standard, often used libs is loaded if bLoadLibs is true (default).
+
+   if ( bLoadLibs )   // note that this section could be programmed in python
+   {
+   // follow TRint to minimize differences with CINT
+      ProcessLine( "#include <iostream>", kTRUE );
+      ProcessLine( "#include <_string>",  kTRUE ); // for std::string iostream.
+      ProcessLine( "#include <vector>",   kTRUE ); // needed because they're used within the
+      ProcessLine( "#include <pair>",     kTRUE ); //  core ROOT dicts and CINT won't be able
+                                                   //  to properly unload these files
+
+   // allow the usage of ClassDef and ClassImp in interpreted macros
+      ProcessLine( "#include <RtypesCint.h>", kTRUE );
+
+   // disallow the interpretation of Rtypes.h, TError.h and TGenericClassInfo.h
+      ProcessLine( "#define ROOT_Rtypes 0", kTRUE );
+      ProcessLine( "#define ROOT_TError 0", kTRUE );
+      ProcessLine( "#define ROOT_TGenericClassInfo 0", kTRUE );
+
+   // the following libs are also useful to have, make sure they are loaded...
+      gROOT->LoadClass("TMinuit",     "Minuit");
+      gROOT->LoadClass("TPostScript", "Postscript");
+      gROOT->LoadClass("THtml",       "Html");
+   }
+
+// save current interpreter context
+   gInterpreter->SaveContext();
+   gInterpreter->SaveGlobalsContext();
+
+// prevent ROOT from exiting python
+   SetReturnFromRun( kTRUE );
+}
+
+
+//- static public members ----------------------------------------------------
+Bool_t PyROOT::TPyROOTApplication::CreatePyROOTApplication( Bool_t bLoadLibs )
+{
+// Create a TPyROOTApplication. Returns false if a gApplication is not null.
+
+   if ( ! gApplication ) {
+   // retrieve arg list from python, translate to raw C, pass on
+      PyObject* argl = PySys_GetObject( const_cast< char* >( "argv" ) );
+
+      int argc = argl ? PyList_Size( argl ) : 1;
+      char** argv = new char*[ argc ];
+      for ( int i = 1; i < argc; ++i )
+         argv[ i ] = PyString_AS_STRING( PyList_GET_ITEM( argl, i ) );
+      argv[ 0 ] = Py_GetProgramName();
+
+      gApplication = new TPyROOTApplication( "PyROOT", &argc, argv, bLoadLibs );
+      return kTRUE;
+   }
+
+   return kFALSE;
+}
+
+//____________________________________________________________________________
+Bool_t PyROOT::TPyROOTApplication::InitROOTGlobals()
+{
+// Setup the basic ROOT globals gBenchmark, gStyle, gProgname, if not already
+// set. Always returns true.
+
+   if ( ! gBenchmark ) gBenchmark = new TBenchmark();
+   if ( ! gStyle ) gStyle = new TStyle();
+
+   if ( ! gProgName )              // should have been set by TApplication
+      gSystem->SetProgname( Py_GetProgramName() );
+
+   return kTRUE;
+}
+
+//____________________________________________________________________________
+Bool_t PyROOT::TPyROOTApplication::InitCINTMessageCallback()
+{
+// Install CINT message callback which will turn CINT error message into
+// python exceptions. Always returns true.
+
+   G__set_errmsgcallback( (void*)&Utility::ErrMsgCallback );
+   return kTRUE;
+}