Issue2636

classification
Title: Jython 2.7.1 - Readonly attribute error
Type: behaviour Severity: normal
Components: Core Versions: Jython 2.7
Milestone:
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: jeff.allen, lucabrasi
Priority: Keywords:

Created on 2017-10-28.03:22:03 by lucabrasi, last changed 2017-10-30.14:48:24 by jeff.allen.

Messages
msg11633 (view) Author: (lucabrasi) Date: 2017-10-28.03:21:59
Hi,

After upgrading to Jython 2.7.1 , we're facing issue with pyangbind Python library (This is a library that generates Python classes from a YANG model). Jython 2.7.1 throws AttributeError readonly exception when calling yangtypes.py from pyangbind library.

After investigation, it seems error is similar as described here: https://stackoverflow.com/questions/12891021/jython-attributeerror-read-only-attr

However, we don't see this issue with Jython 2.7.0

I've attached the yangtypes.py file from pyangbind library.

Thanks
msg11634 (view) Author: (lucabrasi) Date: 2017-10-28.05:47:55
Below is the Jython traceback:

File "/data/naas/ServicePackages/servicemodel/controller/devices/device/vrfs/vrf/__init__.py", line 67, in __init__
    self.__router_eigrp = YANGDynClass(base=router_eigrp.router_eigrp, is_container='container', yang_name="router-eigrp", module_name="l3features", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='http://anutanetworks.com/l3features', defining_module='l3features', yang_type='container', is_config=True)
  File "/data/naas/ServicePackages/pyangbind/lib/yangtypes.py", line 1167, in YANGDynClass
    return YANGBaseClass(*args, **kwargs)
  File "/data/naas/ServicePackages/pyangbind/lib/yangtypes.py", line 997, in __init__
    self._yang_name = yang_name
TypeError: readonly attribute


One workaround is to change the __slots__ from pyangbind to use a different name (Eg: self._yang_myname in this case). But this requires a lot of side changes in pyanglib:

class YANGBaseClass(base_type):
    # we only create slots for things that are restricted
    # in adding attributes to them - this means containing
    # data nodes. This means that we can allow
    # leaf._someattr to be used by consuming code - it
    # also fixes an issue whereby we could set __slots__
    # and try and inherit a variable-length inbuilt such
    # as long, which is not allowed.
    if yang_type in ["container", "list"] or is_container == "container":
      __slots__ = tuple(clsslots)

    _pybind_base_class = re.sub("<(type|class) '(?P<class>.*)'>", "\g<class>",
                                  str(base_type))

    def __new__(self, *args, **kwargs):
      obj = base_type.__new__(self, *args, **kwargs)
      return obj

    def __init__(self, *args, **kwargs):
      self._default = False
      self._mchanged = False
      self._yang_myname = yang_name
      self._mymodule_name = module_name
      self._parent = parent_instance
      self._choice = choice_member
      self._path_helper = path_helper
      self._supplied_register_path = supplied_register_path
      self._base_type = base_type
      self._is_leaf = is_leaf
      self._is_container = is_container
      self._is_config = is_config
      self._extensionsd = extensions
      self._extmethods = extmethods
      self._is_keyval = is_keyval
      self._register_paths = register_paths
      self._mynamespace = namespace
      self._yang_type = yang_type
      self._defining_module = defining_module
      self._metadata = {}
      self._empty_tag = False


clsslots = ['_default', '_mchanged', '_yang_myname', '_mymodule_name', '_choice', '_parent',
                 '_supplied_register_path', '_path_helper', '_base_type',
                 '_is_leaf', '_is_container', '_extensionsd',
                 '_pybind_base_class', '_extmethods', '_is_keyval',
                 '_register_paths', '_mynamespace', '_yang_type',
                 '_defining_module', '_metadata', '_is_config', '_empty_tag']
msg11639 (view) Author: Jeff Allen (jeff.allen) Date: 2017-10-30.14:48:23
Thanks for bringing this up. I think the explanation in the Stackoverflow post is probably correct. If so, it should be possible to make a toy example, separate from the given library.

I do not know of anything that would make _yang_name a special name.

Jython attempts to infer readability from the presence of getters and setters in some circumstances. The intention is to make Java Beans into objects with attributes. I'm surprised to see it in a pure Python class, where clearly it ├Čnterferes with perfectly proper Python.

Perhaps a work-around is to add a setter for the troublesome attribute? (Not tried this.)
History
Date User Action Args
2017-10-30 14:48:24jeff.allensettype: behaviour
messages: + msg11639
nosy: + jeff.allen
2017-10-30 10:58:14lucabrasisetfiles: - yangtypes.py
2017-10-28 05:56:47lucabrasisettitle: Python 2.7.1 - Readonly attribute error -> Jython 2.7.1 - Readonly attribute error
2017-10-28 05:47:56lucabrasisetmessages: + msg11634
2017-10-28 03:22:03lucabrasicreate