# HG changeset patch # Parent a1d725ae3712800117f0b99fc21e9b4373063050 # User Jezreel Ng Handle dotted attribute strings correctly in attrgetter. diff --git a/Lib/test/test_operator.py b/Lib/test/test_operator.py --- a/Lib/test/test_operator.py +++ b/Lib/test/test_operator.py @@ -362,17 +362,16 @@ class OperatorTestCase(unittest.TestCase def test_is_not(self): a = b = 'xyzpdq' c = a[:3] + b[3:] self.failUnlessRaises(TypeError, operator.is_not) self.failIf(operator.is_not(a, b)) self.failUnless(operator.is_not(a,c)) - @unittest.skip("FIXME: broken") def test_attrgetter(self): class A: pass a = A() a.name = 'arthur' f = operator.attrgetter('name') self.assertEqual(f(a), 'arthur') f = operator.attrgetter('rank') diff --git a/src/org/python/modules/operator.java b/src/org/python/modules/operator.java --- a/src/org/python/modules/operator.java +++ b/src/org/python/modules/operator.java @@ -320,17 +320,21 @@ public class operator extends PyObject i if (name instanceof PyUnicode) { nameStr = ((PyUnicode)name).encode(); } else if (name instanceof PyString) { nameStr = name.asString(); } else { throw Py.TypeError(String.format("attribute name must be string, not '%.200s'", name.getType().fastGetName())); } - return obj.__getattr__(nameStr.intern()); + String[] components = nameStr.split("\\."); + for (String component : components) { + obj = obj.__getattr__(component.intern()); + } + return obj; } } /** * The itemgetter type. */ @ExposedType(name = "operator.itemgetter", isBaseType = false)