ovis-hpc / sos

sos pre-release stable.
https://github.com/ovis-hpc/sos/wiki
Other
4 stars 7 forks source link

Fix Sos Object Python attribute issue #81

Closed narategithub closed 1 year ago

narategithub commented 1 year ago

The Sos.Object.__getattr__ implementation masked the access of some of the builtins attributes, e.g. dir and doc. This caused some inconvenience to Sos Object interaction in the interactive Python shell. This patch modifies the __getattr__ and __setattr__ of Sos.Object to fall back to Python's builtins if it failed to get/set Sos Object attribute so that the built-in interaction like dir() and help() works.

Sos Object Python attribute issue

>>> type(o)
<class 'python.Sos.Object'>
>>> dir(o)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "Sos.pyx", line 5552, in python.Sos.Object.__getattr__
ValueError: Object has no attribute with name '__dict__'
>>> help(o)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.10/_sitebuiltins.py", line 103, in __call__
    return pydoc.help(*args, **kwds)
  File "/usr/lib/python3.10/pydoc.py", line 2013, in __call__
    self.help(request)
  File "/usr/lib/python3.10/pydoc.py", line 2072, in help
    else: doc(request, 'Help on %s:', output=self._output)
  File "/usr/lib/python3.10/pydoc.py", line 1792, in doc
    pager(render_doc(thing, title, forceload))
  File "/usr/lib/python3.10/pydoc.py", line 1765, in render_doc
    object, name = resolve(thing, forceload)
  File "/usr/lib/python3.10/pydoc.py", line 1757, in resolve
    name = getattr(thing, '__name__', None)
  File "Sos.pyx", line 5552, in python.Sos.Object.__getattr__
ValueError: Object has no attribute with name '__name__'
>>>

After applying the patch

>>> type(o)
<class 'python.Sos.Object'>
>>> dir(o)
['__class__', '__del__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__pyx_vtable__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', 'as_ndarray', 'commit', 'delete', 'get_schema', 'index_add', 'index_del', 'release', 'set_array_size', 'type_of']
>>> help(o)

Help on Object object:

class Object(builtins.object)
 |  The Object encapsulates the SOS container object in memory.
 |  To support python-like usage, it implements an internal
 |  dictionary of values indexed by the attribute name, and an
 |  internal list of values indexed by attribute id. From Python,
 |  O['<name>'] will return the value of that attribute as a native
 |  Python object. Similarly, O[<id>] will return the same Python
 |  object where the id == sos_attr_id() of the attribute with
 |  the name <name>.
 |
 |  Methods defined here:
 |
 |  __del__(...)
 |
 |  __delattr__(self, name, /)
 |      Implement delattr(self, name).
 |
 |  __delitem__(self, key, /)
 |      Delete self[key].
 |
 |  __getattr__(...)
 |
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |
 |  __getitem__(self, key, /)
 |      Return self[key].
 |
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |
 |  __reduce__ = __reduce_cython__(...)
 |
 |  __setattr__(self, name, value, /)
 |      Implement setattr(self, name, value).
 |
 |  __setitem__(self, key, value, /)
 |      Set self[key] to value.
 |
 |  __setstate__ = __setstate_cython__(...)
 |
 |  as_ndarray(...)
 |      Return the object data or an attributes data as an ndarray of the
 |      specified type
 |
 |      Positional Parameters:
 |      -- The name of the object attribute
 |
 |      Keyword parameters:
 |      eltype - The type of each element in the ndarray