Changeset 5499


Ignore:
Timestamp:
Jan 16, 2012 12:00:00 AM (8 years ago)
Author:
wehart
Message:

Changes to allow dict objects to be passed in and returned from functors. This
allows users to largely ignore the fact that the Options object is used.

Location:
coopr.core/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • coopr.core/trunk/coopr/core/_task.py

    r5497 r5499  
    2121        if self._fn is None:
    2222            raise RuntimeError, "This is a bad definition of a CooprTask.  The '_fn' method is not defined"
     23        #
    2324        # TODO: verify required options here
     25        #
     26        data = self._kwds.get('data', None)
     27        if not data is None and type(data) is dict:
     28            _data = pyutilib.misc.Options()
     29            _data.update(data)
     30            self._kwds['data'] = _data
    2431        if 'data' in self._kwargs:
    2532            data = self._kwds.get('data', None)
    2633            retval = self._fn(**self._kwds)
    2734        else:
    28             #print "HERE",self._kwds
    2935            data = self._kwds.pop('data')
    30             #print "HERE",self._kwds
    3136            retval = self._fn(data, **self._kwds)
    3237        if retval is None or id(data) == id(retval):
    3338            self._retval = pyutilib.misc.Options(data=data)
     39        elif type(retval) is dict:
     40            self._retval = pyutilib.misc.Options()
     41            self._retval.update(retval)
    3442        else:
    3543            if not isinstance(retval, pyutilib.misc.Options):
     
    6472# Decorate functions that are Coopr tasks
    6573#
    66 # TODO: verify that this function hasn't been defined before
    67 # TODO: implement 'implements' and move to PCA tasks
    68 #
    69 def coopr_api(fn=None, implements=None, outputs=None):
     74def coopr_api(fn=None, implements=None, outputs=None, namespace=None):
    7075
    7176    def my_decorator(fn):
  • coopr.core/trunk/coopr/core/tests/test_task.py

    r5497 r5499  
    2828        self.assertEquals(retval.data.b, [2,2])
    2929
     30    def test1a(self):
     31        """Simple test: no keyword arguments or return values"""
     32        @coopr_api
     33        def test1a(data):
     34            """
     35            Required:
     36                data: input data
     37            Return:
     38                data: output data
     39            """
     40            data.a = 2
     41            data.b[0] = 2
     42        #
     43        options = pyutilib.misc.Options()
     44        options.a = 1
     45        options.b = [1,2]
     46        retval = test1a(options)
     47        self.assertEquals(retval.data.a, 2)
     48        self.assertEquals(retval.data.b, [2,2])
     49        retval = test1a(data=options)
     50        self.assertEquals(retval.data.a, 2)
     51        self.assertEquals(retval.data.b, [2,2])
     52
     53    def test1b(self):
     54        """Simple test: data keyword argument, no return values"""
     55        @coopr_api
     56        def test1b(data=None):
     57            data.a = 2
     58            data.b[0] = 2
     59        #
     60        options = pyutilib.misc.Options()
     61        options.a = 1
     62        options.b = [1,2]
     63        retval = test1b(options)
     64        self.assertEquals(retval.data.a, 2)
     65        self.assertEquals(retval.data.b, [2,2])
     66        retval = test1b(data=options)
     67        self.assertEquals(retval.data.a, 2)
     68        self.assertEquals(retval.data.b, [2,2])
     69
    3070    def test2(self):
    3171        """Simple test: no keyword arguments, returning data"""
     
    4686        self.assertEquals(retval.data.b, [2,2])
    4787
    48     def test1a(self):
    49         """Simple test: no keyword arguments or return values"""
    50         @coopr_api
    51         def test1a(data):
    52             """
    53             Required:
    54                 data: input data
    55             Return:
    56                 data: output data
    57             """
    58             data.a = 2
    59             data.b[0] = 2
    60         #
    61         options = pyutilib.misc.Options()
    62         options.a = 1
    63         options.b = [1,2]
    64         retval = test1a(options)
    65         self.assertEquals(retval.data.a, 2)
    66         self.assertEquals(retval.data.b, [2,2])
    67         retval = test1a(data=options)
    68         self.assertEquals(retval.data.a, 2)
    69         self.assertEquals(retval.data.b, [2,2])
    70 
    7188    def test2a(self):
    7289        """Simple test: no keyword arguments, returning data"""
     
    90107        self.assertEquals(retval.data.b, [2,2])
    91108        retval = test2a(data=options)
    92         self.assertEquals(retval.data.a, 2)
    93         self.assertEquals(retval.data.b, [2,2])
    94 
    95     def test1b(self):
    96         """Simple test: data keyword argument, no return values"""
    97         @coopr_api
    98         def test1b(data=None):
    99             data.a = 2
    100             data.b[0] = 2
    101         #
    102         options = pyutilib.misc.Options()
    103         options.a = 1
    104         options.b = [1,2]
    105         retval = test1b(options)
    106         self.assertEquals(retval.data.a, 2)
    107         self.assertEquals(retval.data.b, [2,2])
    108         retval = test1b(data=options)
    109109        self.assertEquals(retval.data.a, 2)
    110110        self.assertEquals(retval.data.b, [2,2])
     
    301301        self.assertEquals(retval.z, 2)
    302302
     303    def test7a(self):
     304        """Test with dict data"""
     305        @coopr_api
     306        def test7a(data, x=1, y=2):
     307            """
     308            Required:
     309                data: input data
     310                x: integer
     311            Optional:
     312                y: integer
     313            """
     314            data.a = y
     315            data.b[0] = x
     316        #
     317        options = {}
     318        options['a'] = 1
     319        options['b'] = [1,2]
     320        retval = test7a(options, x=2)
     321        self.assertEquals(retval.data.a, 2)
     322        self.assertEquals(retval.data.b, [2,2])
     323        retval = test7a(data=options, x=2)
     324        self.assertEquals(retval.data.a, 2)
     325        self.assertEquals(retval.data.b, [2,2])
     326
     327    def test7b(self):
     328        """Test with dict data and return a dictionary"""
     329        @coopr_api
     330        def test7b(data, x=1, y=2):
     331            """
     332            Required:
     333                data: input data
     334                x: integer
     335            Optional:
     336                y: integer
     337            """
     338            data.a = y
     339            data.b[0] = x
     340            return {'data':data}
     341        #
     342        options = {}
     343        options['a'] = 1
     344        options['b'] = [1,2]
     345        retval = test7b(options, x=2)
     346        self.assertEquals(retval.data.a, 2)
     347        self.assertEquals(retval.data.b, [2,2])
     348        retval = test7b(data=options, x=2)
     349        self.assertEquals(retval.data.a, 2)
     350        self.assertEquals(retval.data.b, [2,2])
     351
     352    def test7c(self):
     353        """Test with dict data and return a dictionary"""
     354        @coopr_api
     355        def test7c(data, x=1, y=2):
     356            """
     357            Required:
     358                data: input data
     359                x: integer
     360            Optional:
     361                y: integer
     362            Return:
     363                z: integer
     364            """
     365            data.a = y
     366            data.b[0] = x
     367            return {'data':data, 'z':x}
     368        #
     369        options = {}
     370        options['a'] = 1
     371        options['b'] = [1,2]
     372        retval = test7c(options, x=2)
     373        self.assertEquals(retval.data.a, 2)
     374        self.assertEquals(retval.data.b, [2,2])
     375        retval = test7c(data=options, x=2)
     376        self.assertEquals(retval.data.a, 2)
     377        self.assertEquals(retval.data.b, [2,2])
     378        self.assertEquals(retval.z, 2)
     379
    303380    @unittest.expectedFailure
    304381    def test_err1(self):
  • coopr.core/trunk/doc/api.txt

    r5498 r5499  
    4040Coopr functors are required to have an argument that is a container of labeled data,
    4141which is treated specially. The
    42 container is required to be an +Options+ class, which
     42container is required to be a +dict+ or +Options+ class.  The +Options+ class
    4343generalizes the Python +dict+ class in several ways.  Most notably,
    4444an attribute added to an +Options+ object is also added to the
     
    6666functors, this allows functors to be used with a common API.
    6767
     68If a +dict+ is passed into a functor to provide the container of
     69labeled data, then the functor converts it to a +Options+ object
     70before executing the function.  Since +Options+ objects are subclasses
     71of +dict+, this change may be transparent to the user.  However,
     72this is important in contexts where features of +Options+ are used.
     73
    6874The return value of a Coopr functor is an +Options+ object.  However,
    6975the return value of the function used to declare the constructor
    70 may be either +None+ or an +Options+ object.  If the function returns
     76may be either +None+, a +dict+ object, or an +Options+ object.  If the function returns
    7177+None+ or the +data+ object is returned, then the functor creates
    72 a +Options+ object with an element with key +data+ whose value is
     78an +Options+ object with an element with key +data+ whose value is
    7379the +Options+ object passed into the functor.  Otherwise, if an
    7480+Options+ object is returned then the functor adds an element with
    75 key +data+ if it does not already exist.  Consequently, the return
     81key +data+ if it does not already exist.  If a +dict+ object is returned, then it is converted to an +Options+ object and processed in the same manner. Consequently, the return
    7682value of a Coopr function is an +Options+ object that is guaranteed
    7783to contain a container of labeled data with key +data+.
Note: See TracChangeset for help on using the changeset viewer.