예제 #1
0
def makedocindex():
    """
    Return a string with GPI Index.
    """

    import pydoc

    sections = {}

    from Ganga.Utility.strings import ItemizedTextParagraph

    for sec, names in zip(_GPIhelp_sections.keys(), _GPIhelp_sections.values()):
        itbuf = ItemizedTextParagraph(sec + ":")
        for name, obj, docstring in names:
            # if docstring not provided when exporting the object to GPI then use the docstring generated by pydoc
            if not docstring:
                docstring = pydoc.splitdoc(pydoc.getdoc(obj))[0]
            itbuf.addLine(name, docstring)

        sections[sec] = itbuf.getString()

    return _GPIhelp % sections
예제 #2
0
파일: Proxy.py 프로젝트: wvengen/lgipilot
def GPIProxyClassFactory(name, pluginclass):

    def helptext(f,s):
        f.__doc__ = s % {'classname':name,'objname':name.lower(),'shortvarname':name[0].lower()}
    
    # construct the class on-the-fly using the functions below as methods for the new class

    def _init(self,*args,**kwds):
        #if len(args) > 1:
        #    logger.warning('extra arguments in the %s constructor ignored: %s',name,args[1:])

        # at the object level _impl is a ganga plugin object
        self.__dict__['_impl'] = pluginclass()
        self._impl.__construct__(map(stripProxy,args))

        # initialize all properties from keywords of the constructor
        for k in kwds:
            if self._impl._schema.hasAttribute(k):
                setattr(self,k,kwds[k])
            else:
                logger.warning('keyword argument in the %s constructur ignored: %s=%s (not defined in the schema)',name,k,kwds[k])
        
        self._impl._proxyObject = self
        self._impl._auto__init__()

    from Ganga.Utility.strings import ItemizedTextParagraph

    itbuf = ItemizedTextParagraph('Properties:',linesep='')

    for n,item in pluginclass._schema.allItems():
        if not item['hidden']:
            itbuf.addLine(n,item.describe())

    if not pluginclass.__doc__:
        pluginclass.__doc__ = 'Documentation missing.'

    pluginclass.__doc__.strip()
    pluginclass.__doc__ +=  "\n\n" 
        
    publicdoc = pluginclass.__doc__ + itbuf.getString()
    helptext(pluginclass,'This is a Ganga.GPI.%(classname)s implementation class. Refer to Ganga.GPI.%(classname)s.__doc__ for documentation.')
    
    helptext(_init, """GPI %(classname)s object constructor:
    %(classname)s() : create %(objname)s with default settings;
    %(classname)s(%(shortvarname)s) : make a copy of %(shortvarname)s;
    %(classname)s(%(shortvarname)s,x=a,...): make a copy of %(shortvarname)s and set property 'x' to a, etc..
    """)
        
    def _str(self):
        import StringIO
        sio = StringIO.StringIO()
        self._impl.printSummaryTree(0,0,'',out = sio)
        return sio.getvalue()
    helptext(_str,"""Return a printable string representing %(classname)s object as a tree of properties.""")

    def _repr(self):
        try:
            return self._impl._repr()
        except AttributeError:
            return '<'+repr(self._impl)+' PROXY at '+hex(abs(id(self)))+'>'
    helptext(_repr,"Return an short representation of %(classname)s object.")

    def _eq(self,x):
        result = False
        if isinstance(x, GPIProxyObject): result = self._impl.__eq__(x._impl)
        else: result = self._impl.__eq__(x)
        return result
    helptext(_eq,"Equality operator (==), compare the %(classname)s properties which are declared as [comparable].")

    def _ne(self,x):
        return self._impl.__ne__(x._impl)
    helptext(_ne,"Non-equality operator (!=).")

    def _copy(self, unprepare=None):
        logger.debug('unprepare is %s', str(unprepare))
        if unprepare is None:
            if prepconfig['unprepare_on_copy'] is True:
                if hasattr(self,'is_prepared') or hasattr(self,'application'):
                    unprepare = True

        if hasattr(self,'application'):
            if hasattr(self.application,'is_prepared'):
                if self.application.is_prepared is not None and self.application.is_prepared \
                           is not True and os.path.isdir(os.path.join(shared_path,self.application.is_prepared.name)):
                    from Ganga.Core.GangaRepository import getRegistry
                    shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef()) 
                    logger.debug('increasing counter from proxy.py')
                    shareref.increase(self.application.is_prepared.name)
                    logger.debug('Found ShareDir directory: %s' % self.application.is_prepared.name)
                elif self.application.is_prepared is not None and self.application.is_prepared \
                           is not True and not os.path.isdir(os.path.join(shared_path,self.application.is_prepared.name)):
                    logger.error('ShareDir directory not found: %s' % self.application.is_prepared.name)
                    logger.error('Unpreparing Job #%s' % self.id)
                    from Ganga.Core.GangaRepository import getRegistry
                    shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef()) 
                    shareref.increase(self.application.is_prepared.name)
                    self.unprepare()
    
        if hasattr(self,'is_prepared') and self.is_prepared is not None and self.is_prepared \
                           is not True and not os.path.isdir(os.path.join(shared_path,self.is_prepared.name)):
            logger.error('ShareDir directory not found: %s' % self.is_prepared.name)
            logger.error('Unpreparing %s application' % self._impl._name)
            self.unprepare()

            
        if unprepare is True:
            c = self._impl.clone()
            if hasattr(c,'is_prepared') and c._getRegistry() is None:
                from Ganga.Core.GangaRepository import getRegistry
                shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef()) 
                shareref.increase(self.is_prepared.name)
            c._auto__init__(unprepare=True)
        else:
            c = self._impl.clone()
            c._auto__init__()
        return GPIProxyObjectFactory(c)

    helptext(_copy,"Make an identical copy of self.")
    
    def _setattr(self,x,v):
        'something'
        ## need to know about the types that require metadata attribute checking
        ## this allows derived types to get same behaviour for free.
        from Ganga.GPIDev.Lib.Job.Job import Job
        from Ganga.GPIDev.Lib.Tasks.Task import Task
        from Ganga.GPIDev.Lib.Tasks.Transform import Transform        
        metadata_objects=[Job]
        if x == '_impl':
            raise AttributeError("Internal implementation object '_impl' cannot be reassigned")

        if not self._impl._schema.hasAttribute(x):
            if True in (isType(self,t) for t in metadata_objects) and x in self._impl.metadata.data.keys():
                raise GangaAttributeError("Metadata item '%s' cannot be modified" % x)       
            raise GangaAttributeError("'%s' has no attribute '%s'" % (self._impl._name,x))

        object.__setattr__(self,x,v)
    helptext(_setattr,"""Set a property of %(classname)s with consistency and safety checks.
Setting a [protected] or a unexisting property raises AttributeError.""")

    def _getattr(self,name):
        ## need to know about the types that require metadata attribute checking
        ## this allows derived types to get same behaviour for free.
        from Ganga.GPIDev.Lib.Job.Job import Job
        from Ganga.GPIDev.Lib.Tasks.Task import Task
        from Ganga.GPIDev.Lib.Tasks.Transform import Transform        
        metadata_objects=[Job]
        if True in (isType(self,t) for t in metadata_objects):
            try:
                return self.metadata[name]
            except:
                return object.__getattribute__(self,name)
        return object.__getattribute__(self,name)

    # but at the class level _impl is a ganga plugin class
    d = { '_impl' : pluginclass,
          '__init__' : _init,
          '__str__' : _str,
          '__repr__': _repr,
          '__eq__': _eq,
          '__ne__': _ne,
          'copy' : _copy,
          '__doc__' : publicdoc,
          '__setattr__': _setattr,
          '__getattr__': _getattr
         }

    ## TODO: this makes GangaList inherit from the list
    ## this is not tested and specifically the TestGangaList/testAllListMethodsExported should be verified 
    ##if name == "GangaList":
    ##    return type(name, (GPIProxyObject,list), d)
    
    return type(name, (GPIProxyObject,), d)
예제 #3
0
파일: Proxy.py 프로젝트: alexpearce/ganga
def GPIProxyClassFactory(name, pluginclass):
    # type: (str, type(GangaObject)) -> type(GPIProxyObject)
    """
    Args:
        name: the name of the proxy class
        pluginclass: the ``GangaObject`` subclass to wrap

    Returns:
        a new type which wraps ``pluginclass``
    """

    def helptext(f, s):
        if name == '' or name is None:
            _name = ' '
        else:
            _name = name
        f.__doc__ = s % {'classname': _name, 'objname': _name.lower(), 'shortvarname': _name[0].lower()}

    # construct the class on-the-fly using the functions below as methods for
    # the new class

    def _init(self, *args, **kwds):

        ## Zero-th fully initialize self before moving on
        GPIProxyObject.__init__(self)

        ## THE ORDER IN HOW AN OBJECT IS INITIALIZED IS IMPORTANT AND HAS BEEN DOUBLE CHECKED - rcurrie


        ## If we're only constructing a raw Proxy to wrap an existing object lets wrap that and return
        proxy_obj_str = '_proxy_impl_obj_to_wrap'

        if proxy_obj_str in kwds.keys():
            instance = kwds[proxy_obj_str]
            ## Even if we're wrapping something such as here make sure we set all of the proxy related attributes correctly.
            ## Setting of these attributes shold be done here within this class and should probably be properly be done on proxy construction. aka. here
        else:
            ## FIRST INITALIZE A RAW OBJECT INSTANCE CORRESPONDING TO 'pluginclass'
            ## Object was not passed by construction so need to construct new object for internal use
            instance = pluginclass()

        ## Avoid intercepting any of the setter method associated with the implRef as they could trigger loading from disk
        setattr(self, implRef, instance)
        instance.__dict__[proxyObject] = self

        ## Need to avoid any setter methods for GangaObjects
        ## Would be very nice to remove this entirely as I'm not sure a GangaObject should worry about it's proxy (if any)

        if proxy_obj_str in kwds.keys():
            # wrapping not constructing so can exit after determining that the proxy attributes are setup correctly
            return

        ## SECOND WE NEED TO MAKE SURE THAT OBJECT ID IS CORRECT AND THIS DOES THINGS LIKE REGISTER A JOB WITH THE REPO

        instance._auto__init__()

        ## All objects with an _auto__init__ method need to have that method called and we set the various node attributes here based upon the schema
        for key, _val in stripProxy(self)._schema.allItems():
            if not _val['protected'] and not _val['hidden'] and isType(_val, ComponentItem) and key not in Node._ref_list:
                val = stripProxy(getattr(self, key))
                if isinstance(val, GangaObject):
                    val._auto__init__()
                    instance.setNodeAttribute(key, stripProxy(val))
                else:
                    instance.setNodeAttribute(key, stripProxy(val))


        ## THIRD(?) CONSTRUCT THE OBJECT USING THE ARGUMENTS WHICH HAVE BEEN PASSED
        ## e.g. Job(application=exe, name='myJob', ...) or myJob2 = Job(myJob1)
        ## THIS IS PRIMARILY FOR THE 2ND EXAMPLE ABOVE

        ## DOESN'T MAKE SENSE TO KEEP PROXIES HERE AS WE MAY BE PERFORMING A PSEUDO-COPY OP
        clean_args = [stripProxy(arg) for arg in args]
        try:
            stripProxy(self).__construct__(clean_args)
        except TypeError:
            stripProxy(self).__construct__([])


        ## FOURTH ALLOW FOR APPLICATION AND IS_PREPARED etc TO TRIGGER RELAVENT CODE AND SET THE KEYWORDS FROM THE SCHEMA AGAIN
        ## THIS IS MAINLY FOR THE FIRST EXAMPLE ABOVE

        ## THIS CORRECTLY APPLIES A PROXY TO ALL OBJECT ATTRIBUTES OF AN OBJECT CREATED WITHIN THE GPI

        # initialize all properties from keywords of the constructor
        for k in kwds:
            if stripProxy(self)._schema.hasAttribute(k):
                this_arg = stripProxy(kwds[k])
                if hasattr(this_arg, '_auto__init__'):
                    this_arg._auto__init__()

                ## Copying this from the __set__ method in the Proxy descriptor

                if k == 'application':
                    ProxyDataDescriptor.__app_set__(self, this_arg)
                if k == 'is_prepared':
                    ProxyDataDescriptor.__prep_set__(self, this_arg)


                raw_self = stripProxy(self)

                if type(this_arg) is str:
                    this_arg = stripProxy(runtimeEvalString(raw_self, k, this_arg))
                    if hasattr(this_arg, '_auto__init__'):
                        this_arg._auto__init__()

                if type(this_arg) is str:
                    raw_self.setNodeAttribute(k, this_arg)
                    continue
                else:
                    item = pluginclass._schema.getItem(k)

                    # unwrap proxy
                    if item.isA(ComponentItem):
                        from .Filters import allComponentFilters
                        cfilter = allComponentFilters[item['category']]
                        stripper = lambda v: stripComponentObject(v, cfilter, item)
                    else:
                        stripper = None

                    if item['sequence']:
                        this_arg = ProxyDataDescriptor.__sequence_set__(stripper, raw_self, this_arg, k)
                    else:
                        if stripper is not None:
                            this_arg = stripper(this_arg)
                    # apply attribute filter to component items
                    if item.isA(ComponentItem):
                        this_arg = ProxyDataDescriptor._stripAttribute(raw_self, this_arg, k)

                    if hasattr(this_arg, '_auto__init__'):
                        this_arg._auto__init__()

                    raw_self.setNodeAttribute(k, this_arg)
            else:
                logger.warning('keyword argument in the %s constructur ignored: %s=%s (not defined in the schema)', name, k, kwds[k])

        ## end of _init
        return

    from Ganga.Utility.strings import ItemizedTextParagraph

    itbuf = ItemizedTextParagraph('Properties:', linesep='')

    for n, item in pluginclass._schema.allItems():
        if not item['hidden']:
            itbuf.addLine(n, item.describe())

    if not pluginclass.__doc__:
        pluginclass.__doc__ = 'Documentation missing.'

    pluginclass.__doc__.strip()
    pluginclass.__doc__ += "\n\n"

    publicdoc = pluginclass.__doc__ + itbuf.getString()

    helptext(_init, """GPI %(classname)s object constructor:
    %(classname)s() : create %(objname)s with default settings;
    %(classname)s(%(shortvarname)s) : make a copy of %(shortvarname)s;
    %(classname)s(%(shortvarname)s,x=a,...): make a copy of %(shortvarname)s and set property 'x' to a, etc..
    """)

    def _str(self, interactive=False):
        import cStringIO
        sio = cStringIO.StringIO()
        stripProxy(self).printSummaryTree(0, 0, '', out=sio, interactive=interactive)
        returnable = str(sio.getvalue()).rstrip()
        return returnable
    helptext(_str, """Return a printable string representing %(classname)s object as a tree of properties.""")

    def _repr_pretty_(self, p, cycle):
        if cycle:
            p.text('proxy object...')
            return

        if hasattr(self, implRef):
            raw_self = stripProxy(self)
            if hasattr(raw_self, '_repr_pretty_'):
                raw_self._repr_pretty_(p, cycle)
            elif hasattr(raw_self, '_display'):
                p.text(raw_self._display())
            else:
                #try:
                p.text(self.__str__(interactive=True))
                #except:
                ##    p.text(self.__str__())
        else:
            #try:
            p.text(self.__str__(interactive=True))
            #except:
            #    p.text(self.__str__())

    helptext(_repr_pretty_, """Return a nice string to be printed in the IPython termial""")

    def _repr(self):
        has_proxy = hasattr(self, implRef)
        if has_proxy:
            raw_proxy = stripProxy(self)
        else:
            raw_proxy = None
        if has_proxy and hasattr(raw_proxy, '_repr'):
            return raw_proxy._repr()
        else:
            return '<' + repr(stripProxy(self)) + ' PROXY at ' + hex(abs(id(self))) + '>'
    helptext(_repr, "Return an short representation of %(classname)s object.")

    def _eq(self, x):
        result = False
        if isType(x, GPIProxyObject) or hasattr(x, implRef):
            result = stripProxy(self).__eq__(stripProxy(x))
        else:
            result = stripProxy(self).__eq__(x)
        return result
    helptext(_eq, "Equality operator (==), compare the %(classname)s properties which are declared as [comparable].")

    def _ne(self, x):
        result = True
        if isType(x, GPIProxyObject) or hasattr(x, implRef):
            result = stripProxy(self).__ne__(stripProxy(x))
        else:
            result = stripProxy(self).__ne__(x)
        return result
    helptext(_ne, "Non-equality operator (!=).")

    def _copy(self, unprepare=None):
        logger.debug('unprepare is %s', str(unprepare))
        if unprepare is None:
            if prepconfig['unprepare_on_copy'] is True:
                if hasattr(self, 'is_prepared') or hasattr(self, 'application'):
                    unprepare = True

        def _getSharedPath():
            Config_conf = getConfig('Configuration')
            return os.path.join(expandfilename(Config_conf['gangadir']), 'shared', Config_conf['user'])

        if hasattr(self, 'application'):
            if hasattr(self.application, 'is_prepared'):
                from Ganga.Utility.files import expandfilename
                if self.application.is_prepared not in [None, True]:
                    if hasattr(self.application.is_prepared, 'name'):
                        shared_path = _getSharedPath()
                        if os.path.isdir(os.path.join(shared_path, self.application.is_prepared.name)):
                            from Ganga.Core.GangaRepository import getRegistry
                            shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef())
                            logger.debug('increasing counter from proxy.py')
                            shareref.increase(self.application.is_prepared.name)
                            logger.debug('Found ShareDir directory: %s' % self.application.is_prepared.name)
                elif self.application.is_prepared not in [None, True]:
                    shared_path = _getSharedPath()
                    if not os.path.isdir(os.path.join(shared_path, self.application.is_prepared.name)):
                        logger.error('ShareDir directory not found: %s' % self.application.is_prepared.name)
                        logger.error('Unpreparing Job #%s' % self.id)
                        from Ganga.Core.GangaRepository import getRegistry
                        shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef())
                        shareref.increase(self.application.is_prepared.name)
                        self.unprepare()

        if unprepare is True:
            if hasattr(self, 'is_prepared'):
                from Ganga.Utility.files import expandfilename
                if self.is_prepared not in [None, True]:
                    if hasattr(self.is_prepared, 'name'):
                        shared_path = _getSharedPath()
                        if not os.path.isdir(os.path.join(shared_path, self.is_prepared.name)):
                            logger.error('ShareDir directory not found: %s' % self.is_prepared.name)
                            logger.error('Unpreparing %s application' % getName(stripProxy(self)))
                            self.unprepare()

            c = stripProxy(self).clone()
            if hasattr(c, 'is_prepared') and c._getRegistry() is None:
                from Ganga.Core.GangaRepository import getRegistry
                shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef())
                shareref.increase(self.is_prepared.name)
            stripProxy(c)._auto__init__(unprepare=True)
        else:
            c = stripProxy(self).clone()
            stripProxy(c)._auto__init__()

        return addProxy(c)

    helptext(_copy, "Make an identical copy of self.")

    def _setattr(self, x, v):
        'This is the setter method in the Proxied Objects'
        #logger.debug("_setattr")
        # need to know about the types that require metadata attribute checking
        # this allows derived types to get same behaviour for free.
        p_Ref = stripProxy(self)
        if p_Ref is not None:
            if not isclass(p_Ref):
                class_type = type(p_Ref)
            else:
                class_type = p_Ref
        else:
            class_type = p_Ref

        if x == implRef and not isinstance(v, class_type):
            raise AttributeError("Internal implementation object '%s' cannot be reassigned" % implRef)

        elif not stripProxy(self)._schema.hasAttribute(x):
            from Ganga.GPIDev.Lib.Job.MetadataDict import MetadataDict
            if hasattr(stripProxy(self), 'metadata') and isType(stripProxy(self).metadata, MetadataDict):
                if x in stripProxy(self).metadata.data.keys():
                    raise GangaAttributeError("Metadata item '%s' cannot be modified" % x)

            if x != implRef:
                raise GangaAttributeError("Can't assign '%s' as it does NOT appear in the object schema for class '%s'" % (x, getName(self)))

        new_v = stripProxy(runtimeEvalString(self, x, v))
        GPIProxyObject.__setattr__(self, x, stripProxy(new_v))


    helptext(_setattr, """Set a property of %(classname)s with consistency and safety checks.
Setting a [protected] or a unexisting property raises AttributeError.""")

    #    def _getattr(self, name):
#        if name == '_impl': return self._impl
#        if '_attribute_filter__get__' in dir(self._impl):
#            return self._impl._attribute_filter__get__(name)
#        return self.name
#        ## need to know about the types that require metadata attribute checking
#        ## this allows derived types to get same behaviour for free.
#        from Ganga.GPIDev.Lib.Job.Job import Job
#        from Ganga.GPIDev.Lib.Tasks.Task import Task
#        from Ganga.GPIDev.Lib.Tasks.Transform import Transform
#        metadata_objects=[Job]
#        if True in (isType(self,t) for t in metadata_objects):
#            try:
#                return self.metadata[name]
#            except:
#                return object.__getattribute__(self,name)
#        return object.__getattribute__(self,name)

    def _getattribute(self, name):

        #logger.debug("_getattribute: %s" % str(name))

        if name.startswith('__') or name == implRef:
            return GPIProxyObject.__getattribute__(self, name)
        else:
            implInstance = stripProxy(self)

            if '_attribute_filter__get__' in dir(implInstance) and \
                    not isType(implInstance, ObjectMetaclass) and \
                    implInstance._schema.hasItem(name) and \
                    not implInstance._schema.getItem(name)['hidden']:
                        returnable = addProxy(implInstance._attribute_filter__get__(name))
            else:
                returnable = GPIProxyObject.__getattribute__(self, name)

        if isType(returnable, GangaObject):
            return addProxy(returnable)
        else:
            return returnable

    # but at the class level _impl is a ganga plugin class
    d = {implRef: pluginclass,
            '__init__': _init,
            '__str__': _str,
            '__repr__': _repr,
            '_repr_pretty_': _repr_pretty_,
            '__eq__': _eq,
            '__ne__': _ne,
            'copy': _copy,
            '__doc__': publicdoc,
            '__setattr__': _setattr,
         #          '__getattr__': _getattr,
            '__getattribute__': _getattribute,
         }

    if not hasattr(pluginclass, '_exportmethods'):
        pluginclass._exportmethods = []

    exported_methods = pluginclass._exportmethods

    # export public methods of this class and also of all the bases
    # this class is scanned last to extract the most up-to-date docstring
    dicts = (b.__dict__ for b in reversed(pluginclass.__mro__))
    for dct in dicts:
        for k in dct:
            if getattr(dct[k], 'exported', False):
                exported_methods.append(k)  # Add all @export'd methods
            if k in exported_methods:
                internal_name = "_export_" + k
                if internal_name not in dct.keys():
                    internal_name = k
                try:
                    method = dct[internal_name]
                except KeyError as err:
                    logger.debug("ObjectMetaClass Error internal_name: %s,\t d: %s" % (internal_name, d))
                    logger.debug("ObjectMetaClass Error: %s" % err)
                    raise err

                if not isinstance(method, types.FunctionType):
                    continue
                f = ProxyMethodDescriptor(k, internal_name)
                f.__doc__ = method.__doc__
                d[k] = f

    # export visible properties... do not export hidden properties
    for attr, item in pluginclass._schema.allItems():
        if not item['hidden']:
            d[attr] = ProxyDataDescriptor(attr)

    def __getitem(self, arg):

        if not hasattr(stripProxy(self), '__getitem__'):
            raise AttributeError('I (%s) do not have a __getitem__ attribute' % str(getName(self)))

        output = stripProxy(self).__getitem__(args)

        if isType(output, GangaObject):
            return addProxy(output)
        else:
            return output

    ## NOT ENABLED YET rcurrie
    #if hasattr(pluginclass, '__getitem__'):
    #    d['__getitem__'] = __getitem
    #d['__getitem__'] = __getitem

    # TODO: this makes GangaList inherit from the list
    # this is not tested and specifically the TestGangaList/testAllListMethodsExported should be verified
    # if name == "GangaList":
    # return type(name, (GPIProxyObject,list), d)

    return type(name, (GPIProxyObject,), d)
예제 #4
0
파일: Proxy.py 프로젝트: chrisburr/ganga
def GPIProxyClassFactory(name, pluginclass):

    def helptext(f, s):
        if name == '' or name is None:
            _name = ' '
        else:
            _name = name
        f.__doc__ = s % {'classname': _name, 'objname': _name.lower(), 'shortvarname': _name[0].lower()}

    # construct the class on-the-fly using the functions below as methods for
    # the new class

    def _init(self, *args, **kwds):
        # if len(args) > 1:
        #    logger.warning('extra arguments in the %s constructor ignored: %s',name,args[1:])

        # at the object level _impl is a ganga plugin object
        self.__dict__[proxyRef] = pluginclass()

        clean_args = [stripProxy(arg) for arg in args]

        getattr(self, proxyRef).__construct__(tuple(clean_args))

        # initialize all properties from keywords of the constructor
        for k in kwds:
            if getattr(self, proxyRef)._schema.hasAttribute(k):
                setattr(self, k, kwds[k])
            else:
                logger.warning('keyword argument in the %s constructur ignored: %s=%s (not defined in the schema)', name, k, kwds[k])

        getattr(self, proxyRef)._proxyObject = self
        getattr(self, proxyRef)._auto__init__()

    from Ganga.Utility.strings import ItemizedTextParagraph

    itbuf = ItemizedTextParagraph('Properties:', linesep='')

    for n, item in pluginclass._schema.allItems():
        if not item['hidden']:
            itbuf.addLine(n, item.describe())

    if not pluginclass.__doc__:
        pluginclass.__doc__ = 'Documentation missing.'

    pluginclass.__doc__.strip()
    pluginclass.__doc__ += "\n\n"

    publicdoc = pluginclass.__doc__ + itbuf.getString()

    helptext(pluginclass, 'This is a Ganga.GPI.%(classname)s implementation class. Refer to Ganga.GPI.%(classname)s.__doc__ for documentation.')

    helptext(_init, """GPI %(classname)s object constructor:
    %(classname)s() : create %(objname)s with default settings;
    %(classname)s(%(shortvarname)s) : make a copy of %(shortvarname)s;
    %(classname)s(%(shortvarname)s,x=a,...): make a copy of %(shortvarname)s and set property 'x' to a, etc..
    """)

    def _str(self):
        import cStringIO
        sio = cStringIO.StringIO()
        getattr(self, proxyRef).printSummaryTree(0, 0, '', out=sio)
        return str(sio.getvalue()).rstrip()
    helptext(_str, """Return a printable string representing %(classname)s object as a tree of properties.""")

    def _repr_pretty_(self, p, cycle):
        if cycle:
            p.text('proxy object...')
            return
        p.text(self._display(True))
    helptext(_repr_pretty_, """Return a nice string to be printed in the IPython termial""")

    def _repr(self):
        if hasattr(getattr(self, proxyRef), '_repr'):
            return getattr(self, proxyRef)._repr()
        else:
            return '<' + repr(getattr(self, proxyRef)) + ' PROXY at ' + hex(abs(id(self))) + '>'
    helptext(_repr, "Return an short representation of %(classname)s object.")

    def _eq(self, x):
        result = False
        if isType(x, GPIProxyObject) or hasattr(x, proxyRef):
            result = getattr(self, proxyRef).__eq__(getattr(x, proxyRef))
        else:
            result = getattr(self, proxyRef).__eq__(x)
        return result
    helptext(_eq, "Equality operator (==), compare the %(classname)s properties which are declared as [comparable].")

    def _ne(self, x):
        result = True
        if isType(x, GPIProxyObject) or hasattr(x, proxyRef):
            result = getattr(self, proxyRef).__ne__(getattr(x, proxyRef))
        else:
            result = getattr(self, proxyRef).__ne__(x)
        return result
    helptext(_ne, "Non-equality operator (!=).")

    def _copy(self, unprepare=None):
        logger.debug('unprepare is %s', str(unprepare))
        if unprepare is None:
            if prepconfig['unprepare_on_copy'] is True:
                if hasattr(self, 'is_prepared') or hasattr(self, 'application'):
                    unprepare = True

        def _getSharedPath():
            Config_conf = getConfig('Configuration')
            return os.path.join(expandfilename(Config_conf['gangadir']), 'shared', Config_conf['user'])

        if hasattr(self, 'application'):
            if hasattr(self.application, 'is_prepared'):
                from Ganga.Utility.files import expandfilename
                if self.application.is_prepared not in [None, True]:
                    if hasattr(self.application.is_prepared, 'name'):
                        shared_path = _getSharedPath()
                        if os.path.isdir(os.path.join(shared_path, self.application.is_prepared.name)):
                            from Ganga.Core.GangaRepository import getRegistry
                            shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef())
                            logger.debug('increasing counter from proxy.py')
                            shareref.increase(self.application.is_prepared.name)
                            logger.debug('Found ShareDir directory: %s' % self.application.is_prepared.name)
                elif self.application.is_prepared not in [None, True]:
                    shared_path = _getSharedPath()
                    if not os.path.isdir(os.path.join(shared_path, self.application.is_prepared.name)):
                        logger.error('ShareDir directory not found: %s' % self.application.is_prepared.name)
                        logger.error('Unpreparing Job #%s' % self.id)
                        from Ganga.Core.GangaRepository import getRegistry
                        shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef())
                        shareref.increase(self.application.is_prepared.name)
                        self.unprepare()

        if unprepare is True:
            if hasattr(self, 'is_prepared'):
                from Ganga.Utility.files import expandfilename
                if self.is_prepared not in [None, True]:
                    if hasattr(self.is_prepared, 'name'):
                        shared_path = _getSharedPath()
                        if not os.path.isdir(os.path.join(shared_path, self.is_prepared.name)):
                            logger.error('ShareDir directory not found: %s' % self.is_prepared.name)
                            logger.error('Unpreparing %s application' % getattr(self, proxyRef)._name)
                            self.unprepare()

            c = getattr(self, proxyRef).clone()
            if hasattr(c, 'is_prepared') and c._getRegistry() is None:
                from Ganga.Core.GangaRepository import getRegistry
                shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef())
                shareref.increase(self.is_prepared.name)
            c._auto__init__(unprepare=True)
        else:
            c = getattr(self, proxyRef).clone()
            c._auto__init__()
        return GPIProxyObjectFactory(c)

    helptext(_copy, "Make an identical copy of self.")

    def _setattr(self, x, v):
        'something'
        # need to know about the types that require metadata attribute checking
        # this allows derived types to get same behaviour for free.
        if x == proxyRef:
            raise AttributeError("Internal implementation object '%s' cannot be reassigned" % proxyRef )

        if not getattr(self, proxyRef)._schema.hasAttribute(x):

            if hasattr(getattr(self, proxyRef), 'metadata') and x in getattr(self, proxyRef).metadata.data.keys():
                raise GangaAttributeError("Metadata item '%s' cannot be modified" % x)

            raise GangaAttributeError("'%s' has no attribute '%s'" % (getattr(self, proxyRef)._name, x))

        object.__setattr__(self, x, v)
    helptext(_setattr, """Set a property of %(classname)s with consistency and safety checks.
Setting a [protected] or a unexisting property raises AttributeError.""")

#    def _getattr(self, name):
#        print "HERE", type(self), name, type(name)
#        if name == '_impl': return self._impl
#        if '_attribute_filter__get__' in dir(self._impl):
#            return self._impl._attribute_filter__get__(name)
#        return self.name
#        ## need to know about the types that require metadata attribute checking
#        ## this allows derived types to get same behaviour for free.
#        from Ganga.GPIDev.Lib.Job.Job import Job
#        from Ganga.GPIDev.Lib.Tasks.Task import Task
#        from Ganga.GPIDev.Lib.Tasks.Transform import Transform
#        metadata_objects=[Job]
#        if True in (isType(self,t) for t in metadata_objects):
#            try:
#                return self.metadata[name]
#            except:
#                return object.__getattribute__(self,name)
#        return object.__getattribute__(self,name)

    def _getattribute(self, name):

        if name.startswith('__') or name in d.keys():
            return object.__getattribute__(self, name)

        pluginclass = object.__getattribute__(self, proxyRef)
        if '_attribute_filter__get__' in dir(pluginclass) and \
            pluginclass.__class__.__name__ != 'ObjectMetaclass' and \
                name in dict(pluginclass._schema.allItems()).keys() and \
            not dict(pluginclass._schema.allItems())[name]['hidden']:
            return addProxy(pluginclass._attribute_filter__get__(name))
        else:
            return object.__getattribute__(self, name)

    # but at the class level _impl is a ganga plugin class
    d = {proxyRef: pluginclass,
         '__init__': _init,
         '__str__': _str,
         '__repr__': _repr,
         '__eq__': _eq,
         '__ne__': _ne,
         'copy': _copy,
         '__doc__': publicdoc,
         '__setattr__': _setattr,
         #          '__getattr__': _getattr,
         '__getattribute__': _getattribute
         }

    if hasattr(pluginclass, '_repr_pretty_'):
        d['_repr_pretty_'] = _repr_pretty_

    # TODO: this makes GangaList inherit from the list
    # this is not tested and specifically the TestGangaList/testAllListMethodsExported should be verified
    # if name == "GangaList":
    # return type(name, (GPIProxyObject,list), d)

    return type(name, (GPIProxyObject,), d)
예제 #5
0
파일: Proxy.py 프로젝트: mjmottram/ganga
def GPIProxyClassFactory(name, pluginclass):
    def helptext(f, s):
        if name == "" or name is None:
            _name = " "
        else:
            _name = name
        f.__doc__ = s % {"classname": _name, "objname": _name.lower(), "shortvarname": _name[0].lower()}

    # construct the class on-the-fly using the functions below as methods for
    # the new class

    def _init(self, *args, **kwds):

        ## THE ORDER IN HOW AN OBJECT IS INITIALIZED IS IMPORTANT AND HAS BEEN DOUBLE CHECKED - rcurrie

        ## FIRST INITALIZE A RAW OBJECT INSTANCE CORRESPONDING TO 'pluginclass'

        # logger.debug("Proxy Object _init")
        global proxyRef, proxyClass
        # if len(args) > 1:
        #    logger.warning('extra arguments in the %s constructor ignored: %s',name,args[1:])

        instance = pluginclass()
        for this_attrib in [proxyRef, proxyClass]:
            if hasattr(instance, this_attrib):
                try:
                    delattr(instance, this_attrib)
                except AttributeError:
                    pass

        ## SECOND WE NEED TO MAKE SURE THAT OBJECT ID IS CORRECT AND THIS DOES THINGS LIKE REGISTER A JOB WITH THE REPO

        # at the object level _impl is a ganga plugin object
        instance.__dict__[proxyObject] = self
        assert id(getattr(instance, proxyObject)) == id(self)
        setattr(self, proxyRef, instance)
        self.__dict__[proxyObject] = self
        assert id(getattr(self, proxyObject)) == id(self)
        raw_obj = getattr(self, proxyRef)
        setattr(raw_obj, proxyObject, self)
        raw_obj._auto__init__()

        from Ganga.GPIDev.Base.Objects import Node

        for key, _val in getattr(self, proxyClass)._schema.allItems():
            if (
                not _val["protected"]
                and not _val["hidden"]
                and isType(_val, Schema.ComponentItem)
                and key not in Node._ref_list
            ):
                val = getattr(self, key)
                if isType(val, Node):
                    stripProxy(val)._setParent(raw_obj)
                setattr(raw_obj, key, addProxy(val))

        ## THIRD CONSTRUCT THE OBJECT USING THE ARGUMENTS WHICH HAVE BEEN PASSED
        ## e.g. Job(application=exe, name='myJob', ...) or myJob2 = Job(myJob1)
        ## THIS IS PRIMARILY FOR THE 2ND EXAMPLE ABOVE

        ## DOESN'T MAKE SENSE TO KEEP PROXIES HERE AS WE MAY BE PERFORMING A PSEUDO-COPY OP
        clean_args = [stripProxy(arg) for arg in args]
        getattr(self, proxyRef).__construct__(tuple(clean_args))

        ## FOURTH ALLOW FOR APPLICATION AND IS_PREPARED etc TO TRIGGER RELAVENT CODE AND SET THE KEYWORDS FROM THE SCHEMA AGAIN
        ## THIS IS MAINLY FOR THE FIRST EXAMPLE ABOVE

        ## THIS CORRECTLY APPLIES A PROXY TO ALL OBJECT ATTRIBUTES OF AN OBJECT CREATED WITHIN THE GPI

        # initialize all properties from keywords of the constructor
        for k in kwds:
            if getattr(self, proxyClass)._schema.hasAttribute(k):
                this_arg = kwds[k]

                ## Copying this from the __set__ method in the Proxy descriptor

                if this_arg == "application":
                    ProxyDataDescriptor.__app_set__(self, this_arg)
                if this_arg == "is_prepared":
                    ProxyDataDescriptor.__prep_set__(self, this_arg)

                raw_self = getattr(self, proxyRef)

                if type(this_arg) is str:
                    this_arg = runtimeEvalString(raw_self, k, this_arg)

                if type(this_arg) is str:
                    setattr(raw_self, k, this_arg)
                    continue
                else:
                    item = pluginclass._schema.getItem(k)

                    # unwrap proxy
                    if item.isA(Schema.ComponentItem):
                        from .Filters import allComponentFilters

                        cfilter = allComponentFilters[item["category"]]
                        stripper = lambda v: stripComponentObject(v, cfilter, item)
                    else:
                        stripper = None

                    if item["sequence"]:
                        this_arg = ProxyDataDescriptor.__sequence_set__(stripper, raw_self, this_arg, k)
                    else:
                        if stripper is not None:
                            this_arg = stripper(this_arg)
                    # apply attribute filter to component items
                    if item.isA(Schema.ComponentItem):
                        this_arg = ProxyDataDescriptor._stripAttribute(raw_self, this_arg, k)

                    if isType(this_arg, Node):
                        setattr(this_arg, proxyObject, None)
                        stripProxy(this_arg)._setParent(raw_self)
                    setattr(raw_self, k, addProxy(this_arg))
            else:
                logger.warning(
                    "keyword argument in the %s constructur ignored: %s=%s (not defined in the schema)",
                    name,
                    k,
                    kwds[k],
                )

        raw_obj = getattr(self, proxyRef)

    from Ganga.Utility.strings import ItemizedTextParagraph

    itbuf = ItemizedTextParagraph("Properties:", linesep="")

    for n, item in pluginclass._schema.allItems():
        if not item["hidden"]:
            itbuf.addLine(n, item.describe())

    if not pluginclass.__doc__:
        pluginclass.__doc__ = "Documentation missing."

    pluginclass.__doc__.strip()
    pluginclass.__doc__ += "\n\n"

    publicdoc = pluginclass.__doc__ + itbuf.getString()

    helptext(
        pluginclass,
        "This is a Ganga.GPI.%(classname)s implementation class. Refer to Ganga.GPI.%(classname)s.__doc__ for documentation.",
    )

    helptext(
        _init,
        """GPI %(classname)s object constructor:
    %(classname)s() : create %(objname)s with default settings;
    %(classname)s(%(shortvarname)s) : make a copy of %(shortvarname)s;
    %(classname)s(%(shortvarname)s,x=a,...): make a copy of %(shortvarname)s and set property 'x' to a, etc..
    """,
    )

    def _str(self):
        global proxyRef
        import cStringIO

        sio = cStringIO.StringIO()
        getattr(self, proxyRef).printSummaryTree(0, 0, "", out=sio)
        return str(sio.getvalue()).rstrip()

    helptext(_str, """Return a printable string representing %(classname)s object as a tree of properties.""")

    def _repr_pretty_(self, p, cycle):
        if cycle:
            p.text("proxy object...")
            return

        global proxyRef

        if hasattr(self, proxyRef):
            raw_self = getattr(self, proxyRef)
            if hasattr(raw_self, "_repr_pretty_"):
                raw_self._repr_pretty_(p, cycle)
            elif hasattr(raw_self, "_display"):
                p.text(raw_self._display())
            else:
                p.text(self.__str__())
        else:
            p.text(self.__str__())

    helptext(_repr_pretty_, """Return a nice string to be printed in the IPython termial""")

    def _repr(self):
        global proxyRef
        has_proxy = hasattr(self, proxyRef)
        if has_proxy:
            raw_proxy = getattr(self, proxyRef)
        else:
            raw_proxy = None
        if has_proxy and hasattr(raw_proxy, "_repr"):
            return raw_proxy._repr()
        else:
            return "<" + repr(getattr(self, proxyRef)) + " PROXY at " + hex(abs(id(self))) + ">"

    helptext(_repr, "Return an short representation of %(classname)s object.")

    def _eq(self, x):
        global proxyRef
        result = False
        if isType(x, GPIProxyObject) or hasattr(x, proxyRef):
            result = getattr(self, proxyRef).__eq__(getattr(x, proxyRef))
        else:
            result = getattr(self, proxyRef).__eq__(x)
        return result

    helptext(_eq, "Equality operator (==), compare the %(classname)s properties which are declared as [comparable].")

    def _ne(self, x):
        global proxyRef
        result = True
        if isType(x, GPIProxyObject) or hasattr(x, proxyRef):
            result = getattr(self, proxyRef).__ne__(getattr(x, proxyRef))
        else:
            result = getattr(self, proxyRef).__ne__(x)
        return result

    helptext(_ne, "Non-equality operator (!=).")

    def _copy(self, unprepare=None):
        global proxyRef
        logger.debug("unprepare is %s", str(unprepare))
        if unprepare is None:
            if prepconfig["unprepare_on_copy"] is True:
                if hasattr(self, "is_prepared") or hasattr(self, "application"):
                    unprepare = True

        def _getSharedPath():
            Config_conf = getConfig("Configuration")
            return os.path.join(expandfilename(Config_conf["gangadir"]), "shared", Config_conf["user"])

        if hasattr(self, "application"):
            if hasattr(self.application, "is_prepared"):
                from Ganga.Utility.files import expandfilename

                if self.application.is_prepared not in [None, True]:
                    if hasattr(self.application.is_prepared, "name"):
                        shared_path = _getSharedPath()
                        if os.path.isdir(os.path.join(shared_path, self.application.is_prepared.name)):
                            from Ganga.Core.GangaRepository import getRegistry

                            shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef())
                            logger.debug("increasing counter from proxy.py")
                            shareref.increase(self.application.is_prepared.name)
                            logger.debug("Found ShareDir directory: %s" % self.application.is_prepared.name)
                elif self.application.is_prepared not in [None, True]:
                    shared_path = _getSharedPath()
                    if not os.path.isdir(os.path.join(shared_path, self.application.is_prepared.name)):
                        logger.error("ShareDir directory not found: %s" % self.application.is_prepared.name)
                        logger.error("Unpreparing Job #%s" % self.id)
                        from Ganga.Core.GangaRepository import getRegistry

                        shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef())
                        shareref.increase(self.application.is_prepared.name)
                        self.unprepare()

        if unprepare is True:
            if hasattr(self, "is_prepared"):
                from Ganga.Utility.files import expandfilename

                if self.is_prepared not in [None, True]:
                    if hasattr(self.is_prepared, "name"):
                        shared_path = _getSharedPath()
                        if not os.path.isdir(os.path.join(shared_path, self.is_prepared.name)):
                            logger.error("ShareDir directory not found: %s" % self.is_prepared.name)
                            logger.error("Unpreparing %s application" % getName(getattr(self, proxyRef)))
                            self.unprepare()

            c = getattr(self, proxyRef).clone()
            if hasattr(c, "is_prepared") and c._getRegistry() is None:
                from Ganga.Core.GangaRepository import getRegistry

                shareref = GPIProxyObjectFactory(getRegistry("prep").getShareRef())
                shareref.increase(self.is_prepared.name)
            c._auto__init__(unprepare=True)
        else:
            c = getattr(self, proxyRef).clone()
            c._auto__init__()
        return GPIProxyObjectFactory(c)

    helptext(_copy, "Make an identical copy of self.")

    def _setattr(self, x, v):
        "something"
        # logger.debug("_setattr")
        global proxyRef
        # need to know about the types that require metadata attribute checking
        # this allows derived types to get same behaviour for free.
        if x == proxyRef and not isinstance(v, getattr(self, proxyRef)):
            raise AttributeError("Internal implementation object '%s' cannot be reassigned" % proxyRef)

        if not getattr(self, proxyClass)._schema.hasAttribute(x):

            from Ganga.GPIDev.Lib.Job.MetadataDict import MetadataDict

            if hasattr(getattr(self, proxyClass), "metadata") and isType(
                getattr(self, proxyClass).metadata, MetadataDict
            ):
                if x in getattr(self, proxyClass).metadata.data.keys():
                    raise GangaAttributeError("Metadata item '%s' cannot be modified" % x)

            if x not in [proxyRef, proxyObject]:
                raise GangaAttributeError("'%s' has no attribute '%s'" % (getName(getattr(self, proxyClass)), x))

        new_v = runtimeEvalString(self, x, v)

        object.__setattr__(self, x, new_v)

        # new_obj = getattr(self, x)
        # if hasattr(new_obj, '_setParent'):
        #    new_obj._setParent(self)

    helptext(
        _setattr,
        """Set a property of %(classname)s with consistency and safety checks.
Setting a [protected] or a unexisting property raises AttributeError.""",
    )

    #    def _getattr(self, name):
    #        if name == '_impl': return self._impl
    #        if '_attribute_filter__get__' in dir(self._impl):
    #            return self._impl._attribute_filter__get__(name)
    #        return self.name
    #        ## need to know about the types that require metadata attribute checking
    #        ## this allows derived types to get same behaviour for free.
    #        from Ganga.GPIDev.Lib.Job.Job import Job
    #        from Ganga.GPIDev.Lib.Tasks.Task import Task
    #        from Ganga.GPIDev.Lib.Tasks.Transform import Transform
    #        metadata_objects=[Job]
    #        if True in (isType(self,t) for t in metadata_objects):
    #            try:
    #                return self.metadata[name]
    #            except:
    #                return object.__getattribute__(self,name)
    #        return object.__getattribute__(self,name)

    def _getattribute(self, name):

        # logger.debug("_getattribute: %s" % str(name))

        global proxyRef
        if name.startswith("__") or name in d.keys():
            return object.__getattribute__(self, name)

        proxyInstance = object.__getattribute__(self, proxyRef)
        if (
            "_attribute_filter__get__" in dir(proxyInstance)
            and proxyInstance.__class__.__name__ != "ObjectMetaclass"
            and proxyInstance._schema.hasItem(name)
            and not proxyInstance._schema.getItem(name)["hidden"]
        ):
            return addProxy(proxyInstance._attribute_filter__get__(name))
        else:
            return object.__getattribute__(self, name)

    # but at the class level _impl is a ganga plugin class
    d = {
        proxyRef: pluginclass,
        "__init__": _init,
        "__str__": _str,
        "__repr__": _repr,
        "_repr_pretty_": _repr_pretty_,
        "__eq__": _eq,
        "__ne__": _ne,
        "copy": _copy,
        "__doc__": publicdoc,
        "__setattr__": _setattr,
        #          '__getattr__': _getattr,
        "__getattribute__": _getattribute,
        proxyClass: pluginclass,
        proxyObject: None,
    }

    # TODO: this makes GangaList inherit from the list
    # this is not tested and specifically the TestGangaList/testAllListMethodsExported should be verified
    # if name == "GangaList":
    # return type(name, (GPIProxyObject,list), d)

    return type(name, (GPIProxyObject,), d)
예제 #6
0
파일: Proxy.py 프로젝트: slangrock/ganga
def GPIProxyClassFactory(name, pluginclass):
    # type: (str, type(GangaObject)) -> type(GPIProxyObject)
    """
    Args:
        name: the name of the proxy class
        pluginclass: the ``GangaObject`` subclass to wrap

    Returns:
        a new type which wraps ``pluginclass``
    """
    def helptext(f, s):
        if name == '' or name is None:
            _name = ' '
        else:
            _name = name
        f.__doc__ = s % {
            'classname': _name,
            'objname': _name.lower(),
            'shortvarname': _name[0].lower()
        }

    # construct the class on-the-fly using the functions below as methods for
    # the new class

    def _init(self, *args, **kwds):

        ## Zero-th fully initialize self before moving on
        GPIProxyObject.__init__(self)

        ## THE ORDER IN HOW AN OBJECT IS INITIALIZED IS IMPORTANT AND HAS BEEN DOUBLE CHECKED - rcurrie

        ## If we're only constructing a raw Proxy to wrap an existing object lets wrap that and return
        proxy_obj_str = '_proxy_impl_obj_to_wrap'

        if proxy_obj_str in kwds.keys():
            instance = kwds[proxy_obj_str]
            ## Even if we're wrapping something such as here make sure we set all of the proxy related attributes correctly.
            ## Setting of these attributes shold be done here within this class and should probably be properly be done on proxy construction. aka. here
        else:
            ## FIRST INITALIZE A RAW OBJECT INSTANCE CORRESPONDING TO 'pluginclass'
            ## Object was not passed by construction so need to construct new object for internal use
            instance = pluginclass()

        ## Avoid intercepting any of the setter method associated with the implRef as they could trigger loading from disk
        setattr(self, implRef, instance)

        ## Need to avoid any setter methods for GangaObjects
        ## Would be very nice to remove this entirely as I'm not sure a GangaObject should worry about it's proxy (if any)
        instance.__dict__[proxyObject] = self
        ## THIS SHOLD BE DONE HERE BUT IS DONE IN GANAGOBJECT, PLEASE ADDRESS
        #instance.__dict__[proxyClass] = type(name, (GPIProxyObject,), d)

        if proxy_obj_str in kwds.keys():
            # wrapping not constructing so can exit after determining that the proxy attributes are setup correctly
            return

        ## SECOND WE NEED TO MAKE SURE THAT OBJECT ID IS CORRECT AND THIS DOES THINGS LIKE REGISTER A JOB WITH THE REPO

        instance._auto__init__()

        ## All objects with an _auto__init__ method need to have that method called and we set the various node attributes here based upon the schema
        from Ganga.GPIDev.Base.Objects import GangaObject, Node
        for key, _val in stripProxy(self)._schema.allItems():
            if not _val['protected'] and not _val['hidden'] and isType(
                    _val, ComponentItem) and key not in Node._ref_list:
                val = stripProxy(getattr(self, key))
                if isinstance(val, GangaObject):
                    val._auto__init__()
                    instance.setNodeAttribute(key, stripProxy(val))
                else:
                    instance.setNodeAttribute(key, stripProxy(val))

        ## THIRD(?) CONSTRUCT THE OBJECT USING THE ARGUMENTS WHICH HAVE BEEN PASSED
        ## e.g. Job(application=exe, name='myJob', ...) or myJob2 = Job(myJob1)
        ## THIS IS PRIMARILY FOR THE 2ND EXAMPLE ABOVE

        ## DOESN'T MAKE SENSE TO KEEP PROXIES HERE AS WE MAY BE PERFORMING A PSEUDO-COPY OP
        clean_args = [stripProxy(arg) for arg in args]
        try:
            stripProxy(self).__construct__(clean_args)
        except TypeError:
            stripProxy(self).__construct__([])

        ## FOURTH ALLOW FOR APPLICATION AND IS_PREPARED etc TO TRIGGER RELAVENT CODE AND SET THE KEYWORDS FROM THE SCHEMA AGAIN
        ## THIS IS MAINLY FOR THE FIRST EXAMPLE ABOVE

        ## THIS CORRECTLY APPLIES A PROXY TO ALL OBJECT ATTRIBUTES OF AN OBJECT CREATED WITHIN THE GPI

        # initialize all properties from keywords of the constructor
        for k in kwds:
            if stripProxy(self)._schema.hasAttribute(k):
                this_arg = stripProxy(kwds[k])
                if hasattr(this_arg, '_auto__init__'):
                    this_arg._auto__init__()

                ## Copying this from the __set__ method in the Proxy descriptor

                if k == 'application':
                    ProxyDataDescriptor.__app_set__(self, this_arg)
                if k == 'is_prepared':
                    ProxyDataDescriptor.__prep_set__(self, this_arg)

                raw_self = stripProxy(self)

                if type(this_arg) is str:
                    this_arg = stripProxy(
                        runtimeEvalString(raw_self, k, this_arg))
                    if hasattr(this_arg, '_auto__init__'):
                        this_arg._auto__init__()

                if type(this_arg) is str:
                    raw_self.setNodeAttribute(k, this_arg)
                    continue
                else:
                    item = pluginclass._schema.getItem(k)

                    # unwrap proxy
                    if item.isA(ComponentItem):
                        from .Filters import allComponentFilters
                        cfilter = allComponentFilters[item['category']]
                        stripper = lambda v: stripComponentObject(
                            v, cfilter, item)
                    else:
                        stripper = None

                    if item['sequence']:
                        this_arg = ProxyDataDescriptor.__sequence_set__(
                            stripper, raw_self, this_arg, k)
                    else:
                        if stripper is not None:
                            this_arg = stripper(this_arg)
                    # apply attribute filter to component items
                    if item.isA(ComponentItem):
                        this_arg = ProxyDataDescriptor._stripAttribute(
                            raw_self, this_arg, k)

                    if hasattr(this_arg, '_auto__init__'):
                        this_arg._auto__init__()

                    raw_self.setNodeAttribute(k, this_arg)
            else:
                logger.warning(
                    'keyword argument in the %s constructur ignored: %s=%s (not defined in the schema)',
                    name, k, kwds[k])

        ## end of _init
        return

    from Ganga.Utility.strings import ItemizedTextParagraph

    itbuf = ItemizedTextParagraph('Properties:', linesep='')

    for n, item in pluginclass._schema.allItems():
        if not item['hidden']:
            itbuf.addLine(n, item.describe())

    if not pluginclass.__doc__:
        pluginclass.__doc__ = 'Documentation missing.'

    pluginclass.__doc__.strip()
    pluginclass.__doc__ += "\n\n"

    publicdoc = pluginclass.__doc__ + itbuf.getString()

    helptext(
        _init, """GPI %(classname)s object constructor:
    %(classname)s() : create %(objname)s with default settings;
    %(classname)s(%(shortvarname)s) : make a copy of %(shortvarname)s;
    %(classname)s(%(shortvarname)s,x=a,...): make a copy of %(shortvarname)s and set property 'x' to a, etc..
    """)

    def _str(self, interactive=False):
        import cStringIO
        sio = cStringIO.StringIO()
        stripProxy(self).printSummaryTree(0,
                                          0,
                                          '',
                                          out=sio,
                                          interactive=interactive)
        returnable = str(sio.getvalue()).rstrip()
        return returnable

    helptext(
        _str,
        """Return a printable string representing %(classname)s object as a tree of properties."""
    )

    def _repr_pretty_(self, p, cycle):
        if cycle:
            p.text('proxy object...')
            return

        if hasattr(self, implRef):
            raw_self = stripProxy(self)
            if hasattr(raw_self, '_repr_pretty_'):
                raw_self._repr_pretty_(p, cycle)
            elif hasattr(raw_self, '_display'):
                p.text(raw_self._display())
            else:
                #try:
                p.text(self.__str__(interactive=True))
                #except:
                ##    p.text(self.__str__())
        else:
            #try:
            p.text(self.__str__(interactive=True))
            #except:
            #    p.text(self.__str__())

    helptext(_repr_pretty_,
             """Return a nice string to be printed in the IPython termial""")

    def _repr(self):
        has_proxy = hasattr(self, implRef)
        if has_proxy:
            raw_proxy = stripProxy(self)
        else:
            raw_proxy = None
        if has_proxy and hasattr(raw_proxy, '_repr'):
            return raw_proxy._repr()
        else:
            return '<' + repr(stripProxy(self)) + ' PROXY at ' + hex(
                abs(id(self))) + '>'

    helptext(_repr, "Return an short representation of %(classname)s object.")

    def _eq(self, x):
        result = False
        if isType(x, GPIProxyObject) or hasattr(x, implRef):
            result = stripProxy(self).__eq__(stripProxy(x))
        else:
            result = stripProxy(self).__eq__(x)
        return result

    helptext(
        _eq,
        "Equality operator (==), compare the %(classname)s properties which are declared as [comparable]."
    )

    def _ne(self, x):
        result = True
        if isType(x, GPIProxyObject) or hasattr(x, implRef):
            result = stripProxy(self).__ne__(stripProxy(x))
        else:
            result = stripProxy(self).__ne__(x)
        return result

    helptext(_ne, "Non-equality operator (!=).")

    def _copy(self, unprepare=None):
        logger.debug('unprepare is %s', str(unprepare))
        if unprepare is None:
            if prepconfig['unprepare_on_copy'] is True:
                if hasattr(self, 'is_prepared') or hasattr(
                        self, 'application'):
                    unprepare = True

        def _getSharedPath():
            Config_conf = getConfig('Configuration')
            return os.path.join(expandfilename(Config_conf['gangadir']),
                                'shared', Config_conf['user'])

        if hasattr(self, 'application'):
            if hasattr(self.application, 'is_prepared'):
                from Ganga.Utility.files import expandfilename
                if self.application.is_prepared not in [None, True]:
                    if hasattr(self.application.is_prepared, 'name'):
                        shared_path = _getSharedPath()
                        if os.path.isdir(
                                os.path.join(
                                    shared_path,
                                    self.application.is_prepared.name)):
                            from Ganga.Core.GangaRepository import getRegistry
                            shareref = GPIProxyObjectFactory(
                                getRegistry("prep").getShareRef())
                            logger.debug('increasing counter from proxy.py')
                            shareref.increase(
                                self.application.is_prepared.name)
                            logger.debug('Found ShareDir directory: %s' %
                                         self.application.is_prepared.name)
                elif self.application.is_prepared not in [None, True]:
                    shared_path = _getSharedPath()
                    if not os.path.isdir(
                            os.path.join(shared_path,
                                         self.application.is_prepared.name)):
                        logger.error('ShareDir directory not found: %s' %
                                     self.application.is_prepared.name)
                        logger.error('Unpreparing Job #%s' % self.id)
                        from Ganga.Core.GangaRepository import getRegistry
                        shareref = GPIProxyObjectFactory(
                            getRegistry("prep").getShareRef())
                        shareref.increase(self.application.is_prepared.name)
                        self.unprepare()

        if unprepare is True:
            if hasattr(self, 'is_prepared'):
                from Ganga.Utility.files import expandfilename
                if self.is_prepared not in [None, True]:
                    if hasattr(self.is_prepared, 'name'):
                        shared_path = _getSharedPath()
                        if not os.path.isdir(
                                os.path.join(shared_path,
                                             self.is_prepared.name)):
                            logger.error('ShareDir directory not found: %s' %
                                         self.is_prepared.name)
                            logger.error('Unpreparing %s application' %
                                         getName(stripProxy(self)))
                            self.unprepare()

            c = stripProxy(self).clone()
            if hasattr(c, 'is_prepared') and c._getRegistry() is None:
                from Ganga.Core.GangaRepository import getRegistry
                shareref = GPIProxyObjectFactory(
                    getRegistry("prep").getShareRef())
                shareref.increase(self.is_prepared.name)
            stripProxy(c)._auto__init__(unprepare=True)
        else:
            c = stripProxy(self).clone()
            stripProxy(c)._auto__init__()
        return GPIProxyObjectFactory(c)

    helptext(_copy, "Make an identical copy of self.")

    def _setattr(self, x, v):
        'something'
        #logger.debug("_setattr")
        # need to know about the types that require metadata attribute checking
        # this allows derived types to get same behaviour for free.
        p_Ref = stripProxy(self)
        if p_Ref is not None:
            if not isclass(p_Ref):
                class_type = type(p_Ref)
            else:
                class_type = p_Ref
        else:
            class_type = p_Ref

        if x == implRef and not isinstance(v, class_type):
            raise AttributeError(
                "Internal implementation object '%s' cannot be reassigned" %
                implRef)

        if not stripProxy(self)._schema.hasAttribute(x):
            from Ganga.GPIDev.Lib.Job.MetadataDict import MetadataDict
            if hasattr(stripProxy(self), 'metadata') and isType(
                    stripProxy(self).metadata, MetadataDict):
                if x in stripProxy(self).metadata.data.keys():
                    raise GangaAttributeError(
                        "Metadata item '%s' cannot be modified" % x)

            if x not in [implRef, proxyObject, proxyClass]:
                raise GangaAttributeError("'%s' has no attribute '%s'" %
                                          (getName(stripProxy(self)), x))

        new_v = stripProxy(runtimeEvalString(self, x, v))
        GPIProxyObject.__setattr__(self, x, stripProxy(new_v))

    helptext(
        _setattr,
        """Set a property of %(classname)s with consistency and safety checks.
Setting a [protected] or a unexisting property raises AttributeError.""")

    #    def _getattr(self, name):
    #        if name == '_impl': return self._impl
    #        if '_attribute_filter__get__' in dir(self._impl):
    #            return self._impl._attribute_filter__get__(name)
    #        return self.name
    #        ## need to know about the types that require metadata attribute checking
    #        ## this allows derived types to get same behaviour for free.
    #        from Ganga.GPIDev.Lib.Job.Job import Job
    #        from Ganga.GPIDev.Lib.Tasks.Task import Task
    #        from Ganga.GPIDev.Lib.Tasks.Transform import Transform
    #        metadata_objects=[Job]
    #        if True in (isType(self,t) for t in metadata_objects):
    #            try:
    #                return self.metadata[name]
    #            except:
    #                return object.__getattribute__(self,name)
    #        return object.__getattribute__(self,name)

    def _getattribute(self, name):

        #logger.debug("_getattribute: %s" % str(name))

        GangaObject = _getGangaObject()

        if name.startswith('__') or name == implRef:
            return GPIProxyObject.__getattribute__(self, name)
        else:
            implInstance = stripProxy(self)

            obj_meta = _getMetaClass()

            if '_attribute_filter__get__' in dir(implInstance) and \
                    not isType(implInstance, obj_meta) and \
                    implInstance._schema.hasItem(name) and \
                    not implInstance._schema.getItem(name)['hidden']:
                returnable = addProxy(
                    implInstance._attribute_filter__get__(name))
            else:
                returnable = GPIProxyObject.__getattribute__(self, name)

        if isType(returnable, GangaObject):
            return addProxy(returnable)
        else:
            return returnable

    # but at the class level _impl is a ganga plugin class
    d = {
        implRef: pluginclass,
        '__init__': _init,
        '__str__': _str,
        '__repr__': _repr,
        '_repr_pretty_': _repr_pretty_,
        '__eq__': _eq,
        '__ne__': _ne,
        'copy': _copy,
        '__doc__': publicdoc,
        '__setattr__': _setattr,
        #          '__getattr__': _getattr,
        '__getattribute__': _getattribute,
    }

    if not hasattr(pluginclass, '_exportmethods'):
        pluginclass._exportmethods = []

    exported_methods = pluginclass._exportmethods

    # export public methods of this class and also of all the bases
    # this class is scanned last to extract the most up-to-date docstring
    dicts = (b.__dict__ for b in reversed(pluginclass.__mro__))
    for dct in dicts:
        for k in dct:
            if getattr(dct[k], 'exported', False):
                exported_methods.append(k)  # Add all @export'd methods
            if k in exported_methods:
                internal_name = "_export_" + k
                if internal_name not in dct.keys():
                    internal_name = k
                try:
                    method = dct[internal_name]
                except KeyError as err:
                    logger.debug(
                        "ObjectMetaClass Error internal_name: %s,\t d: %s" %
                        (internal_name, d))
                    logger.debug("ObjectMetaClass Error: %s" % err)
                    raise err

                if not isinstance(method, types.FunctionType):
                    continue
                f = ProxyMethodDescriptor(k, internal_name)
                f.__doc__ = method.__doc__
                d[k] = f

    # export visible properties... do not export hidden properties
    for attr, item in pluginclass._schema.allItems():
        if not item['hidden']:
            d[attr] = ProxyDataDescriptor(attr)

    def __getitem(self, arg):

        if not hasattr(stripProxy(self), '__getitem__'):
            raise AttributeError('I (%s) do not have a __getitem__ attribute' %
                                 str(getName(self)))

        output = stripProxy(self).__getitem__(args)

        if isType(output, _getGangaObject()):
            return addProxy(output)
        else:
            return output

    ## NOT ENABLED YET rcurrie
    #if hasattr(pluginclass, '__getitem__'):
    #    d['__getitem__'] = __getitem
    #d['__getitem__'] = __getitem

    # TODO: this makes GangaList inherit from the list
    # this is not tested and specifically the TestGangaList/testAllListMethodsExported should be verified
    # if name == "GangaList":
    # return type(name, (GPIProxyObject,list), d)

    return type(name, (GPIProxyObject, ), d)