Skip to content

Commit

Permalink
Remove six (#344)
Browse files Browse the repository at this point in the history
* No longer use six in generated binds.

The supported PythonVersion is PY3.

* Replace six.text_type by str

* Replace six.iteritems() by .items()

* Replace six.itervalues() by .values()

* Replace six.string_types

* Add coverage report and pyang output

* Replace six.string_types and six.integer_types

* No longer import six

* Replace six.text_type for str in tests

* Format with black

* Remove six as dependency.

* Remove six from tests
  • Loading branch information
JoseIgnacioTamayo authored Jul 31, 2024
1 parent daf530f commit f3dda7c
Show file tree
Hide file tree
Showing 13 changed files with 67 additions and 101 deletions.
2 changes: 0 additions & 2 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,5 @@ exclude_lines =
if 0:
if __name__ == .__main__.:

# Don't complain about Py3 compatibility shims
if six.PY3:

ignore_errors = True
16 changes: 7 additions & 9 deletions pyangbind/lib/pybindJSON.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
import json
from collections import OrderedDict

import six

from pyangbind.lib.serialise import pybindIETFJSONEncoder, pybindJSONDecoder, pybindJSONEncoder, pybindJSONIOError


Expand All @@ -52,7 +50,7 @@ def loads(d, parent_pymod, yang_base, path_helper=None, extmethods=None, overwri
# that this really expected a dict, so this check simply makes sure
# that if the user really did give us a string, we're happy with that
# without breaking other code.
if isinstance(d, six.string_types + (six.text_type,)):
if isinstance(d, (str,)):
d = json.loads(d, object_pairs_hook=OrderedDict)
return pybindJSONDecoder.load_json(
d, parent_pymod, yang_base, path_helper=path_helper, extmethods=extmethods, overwrite=overwrite
Expand All @@ -61,7 +59,7 @@ def loads(d, parent_pymod, yang_base, path_helper=None, extmethods=None, overwri

def loads_ietf(d, parent_pymod, yang_base, path_helper=None, extmethods=None, overwrite=False):
# Same as above, to allow for load_ietf to work the same way
if isinstance(d, six.string_types + (six.text_type,)):
if isinstance(d, (str,)):
d = json.loads(d, object_pairs_hook=OrderedDict)
return pybindJSONDecoder.load_ietf_json(
d, parent_pymod, yang_base, path_helper=path_helper, extmethods=extmethods, overwrite=overwrite
Expand Down Expand Up @@ -90,7 +88,7 @@ def lookup_subdict(dictionary, key):
if not isinstance(key, list):
raise AttributeError("keys should be a list")
unresolved_dict = {}
for k, v in six.iteritems(dictionary):
for k, v in dictionary.items():
if ":" in k:
k = k.split(":")[1]
unresolved_dict[k] = v
Expand Down Expand Up @@ -132,14 +130,14 @@ def lookup_subdict(dictionary, key):
key_del = []
for t in tree:
keep = True
for k, v in six.iteritems(select):
v = six.text_type(v)
for k, v in select.items():
v = str(v)
if mode == "default" or isinstance(tree, dict):
if keep and not six.text_type(lookup_subdict(tree[t], k.split("."))) == v:
if keep and not str(lookup_subdict(tree[t], k.split("."))) == v:
keep = False
else:
# handle ietf case where we have a list and might have namespaces
if keep and not six.text_type(lookup_subdict(t, k.split("."))) == v:
if keep and not str(lookup_subdict(t, k.split("."))) == v:
keep = False
if not keep:
key_del.append(t)
Expand Down
42 changes: 20 additions & 22 deletions pyangbind/lib/serialise.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,13 @@
from decimal import Decimal
import base64

import six
from enum import IntEnum
from lxml import objectify, etree

from pyangbind.lib.yangtypes import YANGBool, safe_name


if six.PY3:
long = int
long = int


class WithDefaults(IntEnum):
Expand Down Expand Up @@ -108,7 +106,7 @@ def default(self, obj):
return [self.default(i) for i in obj]
# Expand dictionaries
elif isinstance(obj, dict):
return {k: self.default(v) for k, v in six.iteritems(obj)}
return {k: self.default(v) for k, v in obj.items()}

if pybc is not None:
# Special cases where the wrapper has an underlying class
Expand All @@ -119,7 +117,7 @@ def default(self, obj):

# Map based on YANG type
if orig_yangt in ["leafref"]:
return self.default(obj._get()) if hasattr(obj, "_get") else six.text_type(obj)
return self.default(obj._get()) if hasattr(obj, "_get") else str(obj)
elif orig_yangt in ["int64", "uint64"]:
return self.yangt_long(obj)
elif orig_yangt in ["identityref"]:
Expand All @@ -130,9 +128,9 @@ def default(self, obj):
elif orig_yangt in ["int8", "int16", "int32", "uint8", "uint16", "uint32"]:
return self.yangt_int(obj)
elif orig_yangt in ["string", "enumeration"]:
return six.text_type(obj)
return str(obj)
elif orig_yangt in ["binary"]:
return six.text_type(base64.b64encode(obj), "ascii")
return str(base64.b64encode(obj), "ascii")
elif orig_yangt in ["decimal64"]:
return self.yangt_decimal(obj)
elif orig_yangt in ["bool"]:
Expand All @@ -157,12 +155,12 @@ def default(self, obj):
return nlist
elif isinstance(obj, dict):
ndict = {}
for k, v in six.iteritems(obj):
for k, v in obj.items():
ndict[k] = self.default(v)
return ndict
elif isinstance(obj, six.string_types + (six.text_type,)):
return six.text_type(obj)
elif isinstance(obj, six.integer_types):
elif isinstance(obj, (str,)):
return str(obj)
elif isinstance(obj, (int,)):
return int(obj)
elif isinstance(obj, (YANGBool, bool)):
return bool(obj)
Expand All @@ -183,9 +181,9 @@ def map_pyangbind_type(self, map_val, original_yang_type, obj):
# NOTE: this doesn't seem like it needs to be a special case?
return self.yangt_decimal(obj)
elif map_val in ["pyangbind.lib.yangtypes.YANGBinary", "YANGBinary"]:
return six.text_type(base64.b64encode(obj), "ascii")
return str(base64.b64encode(obj), "ascii")
elif map_val in ["unicode"]:
return six.text_type(obj)
return str(obj)
elif map_val in ["pyangbind.lib.yangtypes.YANGBool"]:
if original_yang_type == "empty":
# NOTE: previously with IETF mode the code would fall-through if obj was falsey
Expand All @@ -202,7 +200,7 @@ def map_pyangbind_type(self, map_val, original_yang_type, obj):
elif map_val in ["decimal.Decimal"]:
return self.yangt_decimal(obj)
elif map_val in ["YANGBits"]:
return six.text_type(obj)
return str(obj)

def yangt_int(self, obj):
# for values that are 32-bits and under..
Expand Down Expand Up @@ -232,7 +230,7 @@ class IETFYangDataSerialiser(YangDataSerialiser):
"""

def yangt_long(self, obj):
return six.text_type(obj)
return str(obj)

def yangt_identityref(self, obj):
try:
Expand All @@ -243,10 +241,10 @@ def yangt_identityref(self, obj):
return "%s:%s" % (emod, obj)
except KeyError:
pass
return six.text_type(obj)
return str(obj)

def yangt_decimal(self, obj):
return six.text_type(obj)
return str(obj)

def yangt_empty(self, obj):
return [None] if obj else False
Expand Down Expand Up @@ -541,7 +539,7 @@ def load_xml(d, parent, yang_base, obj=None, path_helper=None, extmethods=None):
try:
chobj.append(child.pyval)
except ValueError:
if six.text_type in chobj._allowed_type:
if str in chobj._allowed_type:
chobj.append(str(child.pyval))
else:
raise
Expand Down Expand Up @@ -640,7 +638,7 @@ def load_json(
# Put keys in order:
okeys = []
kdict = {}
for k, v in six.iteritems(d[key]):
for k, v in d[key].items():
if "__yang_order" not in v:
# Element is not specified in terms of order, so
# push to a list that keeps this order
Expand Down Expand Up @@ -711,9 +709,9 @@ def load_json(

@staticmethod
def check_metadata_add(key, data, obj):
keys = [six.text_type(k) for k in data]
keys = [str(k) for k in data]
if ("@" + key) in keys:
for k, v in six.iteritems(data["@" + key]):
for k, v in data["@" + key].items():
obj._add_metadata(k, v)

@staticmethod
Expand Down Expand Up @@ -755,7 +753,7 @@ def load_ietf_json(

if key == "@":
# Handle whole container metadata object
for k, v in six.iteritems(d[key]):
for k, v in d[key].items():
obj._add_metadata(k, v)
continue
elif "@" in key:
Expand Down
9 changes: 4 additions & 5 deletions pyangbind/lib/xpathhelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
from collections import OrderedDict

import regex
import six
from lxml import etree

from .base import PybindBase
Expand Down Expand Up @@ -172,7 +171,7 @@ def _encode_path(self, path, mode="search", find_parent=False, normalise_namespa

if attributes is not None:
epath += tagname + "["
for k, v in six.iteritems(attributes):
for k, v in attributes.items():
# handling for rfc6020 current() specification
if "current()" in v:
remaining_path = regex.sub("current\(\)(?P<remaining>.*)", r"\g<remaining>", v).split("/")
Expand Down Expand Up @@ -275,7 +274,7 @@ def register(self, object_path, object_ptr, caller=False):

added_item = etree.SubElement(parent_o, tagname, obj_ptr=this_obj_id)
if attributes is not None:
for k, v in six.iteritems(attributes):
for k, v in attributes.items():
added_item.set(k, v)

def unregister(self, object_path, caller=False):
Expand Down Expand Up @@ -306,7 +305,7 @@ def _get_etree(self, object_path, caller=False):
return retr_obj

def get(self, object_path, caller=False):
if isinstance(object_path, six.string_types + (six.text_type,)):
if isinstance(object_path, (str,)):
object_path = self._path_parts(object_path)

return [self._library[i.get("obj_ptr")] for i in self._get_etree(object_path, caller=caller)]
Expand All @@ -320,7 +319,7 @@ def get_unique(self, object_path, caller=False, exception_to_raise=YANGPathHelpe
return obj[0]

def get_list(self, object_path, caller=False, exception_to_raise=YANGPathHelperException):
if isinstance(object_path, six.string_types + (six.text_type,)):
if isinstance(object_path, (str,)):
object_path = self._path_parts(object_path)

parent_obj = self.get_unique(object_path[:-1], caller=caller, exception_to_raise=exception_to_raise)
Expand Down
29 changes: 14 additions & 15 deletions pyangbind/lib/yangtypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
from decimal import Decimal

import regex
import six

# Words that could turn up in YANG definition files that are actually
# reserved names in Python, such as being builtin types. This list is
Expand Down Expand Up @@ -176,7 +175,7 @@ def RestrictedClassType(*args, **kwargs):
type of restriction placed on the class, and the restriction_arg gives
any input data that this function needs.
"""
base_type = kwargs.pop("base_type", six.text_type)
base_type = kwargs.pop("base_type", str)
restriction_type = kwargs.pop("restriction_type", None)
restriction_arg = kwargs.pop("restriction_arg", None)
restriction_dict = kwargs.pop("restriction_dict", None)
Expand All @@ -185,7 +184,7 @@ def RestrictedClassType(*args, **kwargs):
# this gives deserialisers some hints as to how to encode/decode this value
# it must be a list since a restricted class can encapsulate a restricted
# class
current_restricted_class_type = regex.sub("<(type|class) '(?P<class>.*)'>", r"\g<class>", six.text_type(base_type))
current_restricted_class_type = regex.sub("<(type|class) '(?P<class>.*)'>", r"\g<class>", str(base_type))
if hasattr(base_type, "_restricted_class_base"):
restricted_class_hint = getattr(base_type, "_restricted_class_base")
restricted_class_hint.append(current_restricted_class_type)
Expand Down Expand Up @@ -304,7 +303,7 @@ def mp_check(value):
return mp_check

def in_dictionary_check(dictionary):
return lambda i: six.text_type(i) in dictionary
return lambda i: str(i) in dictionary

val = False
try:
Expand Down Expand Up @@ -404,7 +403,7 @@ def TypedListType(*args, **kwargs):
certain types (specified by allowed_type kwarg to the function)
can be added to the list.
"""
allowed_type = kwargs.pop("allowed_type", six.text_type)
allowed_type = kwargs.pop("allowed_type", str)
if not isinstance(allowed_type, list):
allowed_type = [allowed_type]

Expand Down Expand Up @@ -454,11 +453,11 @@ def check(self, v):
tmp = i(v)
passed = True
break
elif i == six.text_type and isinstance(v, six.string_types + (six.text_type,)):
tmp = six.text_type(v)
elif i == str and isinstance(v, (str,)):
tmp = str(v)
passed = True
break
elif i not in six.string_types + (six.text_type,):
elif i not in (str,):
# for anything other than string we try
# and cast. Using things for string or
# unicode gives us strange results because we get
Expand Down Expand Up @@ -590,10 +589,10 @@ def __check__(self, v):
return True

def iteritems(self):
return six.iteritems(self._members)
return self._members.items()

def itervalues(self):
return six.itervalues(self._members)
return self._members.values()

def _key_to_native_key_type(self, k):
if self._keyval is False:
Expand Down Expand Up @@ -630,7 +629,7 @@ def __set(self, *args, **kwargs):
# this is a list that does not have a key specified, and hence
# we generate a uuid that is used as the key, the method then
# returns the uuid for the upstream process to use
k = six.text_type(uuid.uuid1())
k = str(uuid.uuid1())

update = False
if v is not None:
Expand Down Expand Up @@ -777,7 +776,7 @@ def _extract_key(self, obj):
kv = getattr(obj, "_get_%s" % safe_name(k), None)
if kv is None:
raise KeyError("Invalid key attribute specified for object")
ks += "%s " % six.text_type(kv())
ks += "%s " % str(kv())
return ks.rstrip(" ")
else:
kv = getattr(obj, "_get_%s" % safe_name(self._keyval), None)
Expand Down Expand Up @@ -1253,7 +1252,7 @@ def __init__(self, *args, **kwargs):
self._ptr = False
self._require_instance = require_instance
self._type = "unicode"
self._utype = six.text_type
self._utype = str

if len(args):
value = args[0]
Expand Down Expand Up @@ -1301,15 +1300,15 @@ def __init__(self, *args, **kwargs):
if len(path_chk) == 1 and is_yang_leaflist(path_chk[0]):
index = 0
for i in path_chk[0]:
if six.text_type(i) == six.text_type(value):
if str(i) == str(value):
found = True
self._referenced_object = path_chk[0][index]
break
index += 1
else:
found = False
for i in path_chk:
if six.text_type(i) == six.text_type(value):
if str(i) == str(value):
found = True
self._referenced_object = i

Expand Down
Loading

0 comments on commit f3dda7c

Please sign in to comment.