personalrobotics / prpy

Python utilities used by the Personal Robotics Laboratory.
BSD 3-Clause "New" or "Revised" License
62 stars 19 forks source link

Cloned robot `getattr` access can easily cause *major* infinite recursion loop. #262

Closed psigen closed 8 years ago

psigen commented 8 years ago

@mkoval @ClintLiddick: This is a big one.

Accessing any undefined attribute on a cloned robot causes infinite recursion. I think this is because the 'canonical instance' query checks 'actions' or 'detector' causing them to query each other forever.

$ rosrun herbpy console.py --sim

from prpy import Clone, Cloned
with Clone(robot.GetEnv()) as cloned_env:
    cloned_robot = cloned_env.Cloned(robot)
    cloned_robot.banana
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
/home/pkv/ws/src/deps/planning/herbpy/scripts/console.py in <module>()
      1 with Clone(robot.GetEnv()) as cloned_env:
      2     cloned_robot = cloned_env.Cloned(robot)
----> 3     cloned_robot.banana
      4 

/home/pkv/ws/src/deps/planning/prpy/src/prpy/bind.pyc in intercept(self, name)
    112             # we explicitly invoke it on object.
    113             if hasattr(canonical_instance, '__getattr__'):
--> 114                 return canonical_instance.__getattr__(name)
    115             else:
    116                 raise

/home/pkv/ws/src/deps/planning/prpy/src/prpy/base/robot.pyc in __getattr__(self, name)
    112             return wrapper_method
    113         elif (name != 'actions'
--> 114               and hasattr(self, 'actions')
    115               and self.actions is not None
    116               and self.actions.has_action(name)):

/home/pkv/ws/src/deps/planning/prpy/src/prpy/bind.pyc in intercept(self, name)
    112             # we explicitly invoke it on object.
    113             if hasattr(canonical_instance, '__getattr__'):
--> 114                 return canonical_instance.__getattr__(name)
    115             else:
    116                 raise

/home/pkv/ws/src/deps/planning/prpy/src/prpy/base/robot.pyc in __getattr__(self, name)
    122             return wrapper_method
    123         elif (name != 'detector'
--> 124               and hasattr(self, 'detector')
    125               and self.detector is not None
    126               and self.detector.has_perception_method(name)):

/home/pkv/ws/src/deps/planning/prpy/src/prpy/bind.pyc in intercept(self, name)
    112             # we explicitly invoke it on object.
    113             if hasattr(canonical_instance, '__getattr__'):
--> 114                 return canonical_instance.__getattr__(name)
    115             else:
    116                 raise

/home/pkv/ws/src/deps/planning/prpy/src/prpy/base/robot.pyc in __getattr__(self, name)
    112             return wrapper_method
    113         elif (name != 'actions'
--> 114               and hasattr(self, 'actions')
    115               and self.actions is not None
    116               and self.actions.has_action(name)):

/home/pkv/ws/src/deps/planning/prpy/src/prpy/bind.pyc in intercept(self, name)
    112             # we explicitly invoke it on object.
    113             if hasattr(canonical_instance, '__getattr__'):
--> 114                 return canonical_instance.__getattr__(name)
    115             else:
    116                 raise

/home/pkv/ws/src/deps/planning/prpy/src/prpy/base/robot.pyc in __getattr__(self, name)
    122             return wrapper_method
    123         elif (name != 'detector'
--> 124               and hasattr(self, 'detector')
    125               and self.detector is not None
    126               and self.detector.has_perception_method(name)):
[...]
psigen commented 8 years ago

I think I may have fixed this with https://github.com/personalrobotics/prpy/pull/263.