pyangbind icon indicating copy to clipboard operation
pyangbind copied to clipboard

Support of bits type.

Open ashishk1994 opened this issue 9 years ago • 10 comments

Hi,

I see pyangbind doesn't have support of type bits. I think this could be a good feature to extend the pyangbind plugin.

ashishk1994 avatar May 14 '16 12:05 ashishk1994

Hi,

Thanks for the suggestion. I would be happy to review a pull request if this were something that you'd like to contribute.

Kind regards, r.

robshakir avatar May 25 '16 17:05 robshakir

Hi Rob,

Use case:

leaf latitude {
                type bits {
                        bit N { 
                                description
                                        "Latitude bit.";
                        }   
                        bit N2 {
                                description
                                        "Latitude bit.";
                        }
                }
                description
                        "Bit that selects between North and South latitude.";
        }

Representation:

latitude = ["N", "N2"] (Correct)
latitude = ["N2"] (Correct)
latitude = ["N3"] (Incorrect)

I was locating the issue and I had done the following:

  1. In build_elemtype() at line 1203 (plugin/pybind.py), Returned the elemtype for bits as follows:
    if et.arg == "bits":
        bits_dict = {} 
        for bit in et.search('bit'):
           bits_dict[unicode(bit.arg)] = {} 
           position = bit.search_one('position')
           if position is not None:
               bits_dict[unicode(bit.arg)]["position"] = int(position.arg)
        elemtype = {"native_type": """RestrictedClassType(base_type=unicode, \
                                      restriction_type="sub_dict_keys", \
                                      restriction_arg=%s,)""" %
                                      (bits_dict),
                    "restriction_argument": bits_dict,
                    "restriction_type": "sub_dict_keys",
                    "parent_type": "string",
                    "base_type": True}
  1. In yangtypes: at line 286: (lib/yangtypes.py) 2.1: Filled the positions into empty bits in increasing order and added the restriction_tests as follows:
        elif rtype == "sub_dict_keys":
          new_rarg = copy.deepcopy(rarg)
          for k in rarg:
            if k.startswith("@"):
              new_rarg.pop(k, None)

          #populate bits positions
          bits_positions = [] 
          for k in new_rarg:
            if "position" in new_rarg[k]:
              bits_positions.append(int(new_rarg[k]["position"]))
          p = 0
          for k in new_rarg:
            while p in bits_positions:
              p += 1 
            if "position" not in new_rarg[k]:
              new_rarg[k]["position"] = p
            p += 1 
          print new_rarg.keys()
          self._restriction_tests.append(sub_list_check(new_rarg.keys()))
          self._bits_dict = new_rarg
  1. Added the sub_list_check function which checks if the input is present in the list, This function is being used at point 2 above.
      def sub_list_check(lst):
        def sub_lst_check(value):
           for i in value:
                if i not in lst: 
                        return False
           return True 
        return sub_lst_chec

Now, I am compiling my yangfiles with above template of bits. It is compiling fine with below command:

pyang --plugindir $PYBINDPLUGIN -f pybind -o binding.py ietf-lisp-address-types.yang

But in assigning a value to bit as follow is giving the error: obj.latitude=("N", "N2")

Traceback (most recent call last): File "gen.py", line 5, in obj.latitude=("N", "N2")

 File "/home/ashish/odl_test/bits/binding.py", line 333, in _set_latitude
    'generated-type': """YANGDynClass(base=RestrictedClassType(base_type=unicode,                             restriction_type="sub_dict_keys",                       restriction_arg={u'N2': {}, u'N': {}},), is_leaf=True, yang_name="latitude", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace='urn:ietf:params:xml:ns:yang:ietf-lisp-address-types', defining_module='ietf-lisp-address-types', yang_type='bits', is_config=True)""",
ValueError: {'error-string': 'latitude must be of a type compatible with bits', 'generated-type': 'YANGDynClass(base=RestrictedClassType(base_type=unicode, \t\t                      restriction_type="sub_dict_keys", \t\t\t\t      restriction_arg={u\'N2\': {}, u\'N\': {}},), is_leaf=True, yang_name="latitude", parent=self, path_helper=self._path_helper, extmethods=self._extmethods, register_paths=True, namespace=\'urn:ietf:params:xml:ns:yang:ietf-lisp-address-types\', defining_module=\'ietf-lisp-address-types\', yang_type=\'bits\', is_config=True)', 'defined-type': 'ietf-lisp-address-types:bits'}

Can you help me with this, I think I am missing something.

ashishk1994 avatar Jun 23 '16 15:06 ashishk1994

Hi Rob,

Can you please tell me if I am right about my understanding (as explained above).

Thanks

ashishk1994 avatar Jul 04 '16 15:07 ashishk1994

Hi Ashish,

Apologies, I'd missed the update to this issue.

Is there a fork that I can pull to take a look at this by any chance?

The error that you supplied is thrown in the generated bindings when a new instance of the object is created. PyangBind generally treats member variables in the structure as immutable, so that we create a new version of the object rather than trying to mutate the existing one - the creation of the new object throws ValueError in the case that some error is returned during instantiation of the object with type(val, args).

So, to debug the class above, it seems like a good step would be to remove that ValueError being caught, and seeing what the underlying error that is returned is.

Happy to help if you can point me to the code.

Cheers, r.

robshakir avatar Jul 07 '16 09:07 robshakir

Hello,

I am working with a few YANG models that use the YANG built-in type bits. I have found PyangBind to be a valuable tool. By chance is there an update to the bits type support enhancement?

Gayle

gliverm avatar Jan 04 '18 15:01 gliverm

The ietf-netconf-acm.yang module also uses the bits built in type so a module importing this (I am trying to use ietf-system.yang) encounters an error "could not find a match for nacm:access-operations-type type -> [u'bits']" and "TypeError: could not resolve typedefs [u'nacm:access-operations-type']". Does anyone know a way to skip over this error or does the issue need to be resolved?

jmrenshaw avatar Apr 18 '18 13:04 jmrenshaw

You can get around this if you are not planning to use the types in the yang files which use the bits built in types by commenting them out. Not ideal but it works as a short term fix.

jmrenshaw avatar Apr 18 '18 16:04 jmrenshaw

I am using pyangbind with IETF models, and came up with this error. I can not ignore the yang parts that use this type: is there a plan to solve the issue ? Thanks a lot for your help!

EstherLerouzic avatar Jun 17 '19 10:06 EstherLerouzic

You can get around this if you are not planning to use the types in the yang files which use the bits built in types by commenting them out. Not ideal but it works as a short term fix.

This worked for me, thank you.

DouglasAR01 avatar Jul 12 '19 05:07 DouglasAR01

Hi Ashish,

from RFC 6020, I think lexical representation should be: <latitude> N N2 </latitude>

obj.latitude = "N N2" # space delimited

I modified your implementation as follow:

               def sub_list_check(lst):
                    def sub_lst_check(value):
                        if isinstance(value, str) is False:
                            return False
                        bits = value.split()   
                        for i in bits:
                            if i not in lst:
                                return False
                        return True

                    return sub_lst_check

Regards,

LL

hayashi-leo avatar Jun 11 '20 19:06 hayashi-leo

Support for Bits type was added in https://github.com/robshakir/pyangbind/pull/315

JoseIgnacioTamayo avatar Feb 23 '24 07:02 JoseIgnacioTamayo