[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [HTCondor-users] list(ExprTree) infinite loop



> On Nov 19, 2014, at 4:24 PM, Dimitri Maziuk <dmaziuk@xxxxxxxxxxxxx> wrote:
> 
> On 11/19/2014 04:09 PM, Brian Bockelman wrote:
> 
>> Any suggestions from the list on how the semantics should work here?
> 
> I'd expect list(classad.ExprTree("2+2")) to return ("2", "+", "2") (in
> whatever order: infix, rpn, ...)
> 

Hm - I guess I think of that as a "decompose" type operation (the ClassAd C++ API calls it GetComponents).

After further thought, I settled on the following logic for list conversions:
1) If it is a ClassAd list, then convert it to a python list:

>>> list(classad.ExprTree("{1,2,3}"))
[1L, 2L, 3L]

2) If it is a literal value (such as the string "A"), convert it to a python list:

>>> list(classad.ExprTree('"ABC"'))
['A', 'B', 'C']

3) Otherwise, evaluate the expression.  If it evaluates to a List or string value, convert to a python list.  If it cannot be evaluated, throw a type error.

>>> list(classad.ExprTree("strcat(\"ABC\", \"DEF\")"))
['A', 'B', 'C', 'D', 'E', 'F']

4) To get the previous behavior - generate a new expression using the subscript operation, use the function "_get".  So,

With the new logic, the following unit test case will now fail:

    def test_subscript(self):
        ad = classad.ClassAd({'foo': [0,1,2,3]})
        expr = classad.Attribute("foo")[2]
        self.assertTrue(isinstance(expr, classad.ExprTree))
        self.assertEquals(expr.eval(), classad.Value.Undefined)
        self.assertEquals(expr.eval(ad), 2)

but this would work:

    def test_subscript(self):
        ad = classad.ClassAd({'foo': [0,1,2,3]})
        expr = classad.Attribute("foo").get(2)
        self.assertTrue(isinstance(expr, classad.ExprTree))
        self.assertEquals(expr.eval(), classad.Value.Undefined)
        self.assertEquals(expr.eval(ad), 2)

Does this sound good?

Brian