diff --git a/pyangbind/lib/yangtypes.py b/pyangbind/lib/yangtypes.py
index aa6fe79..8b73346 100644
--- a/pyangbind/lib/yangtypes.py
+++ b/pyangbind/lib/yangtypes.py
@@ -377,19 +377,25 @@ def TypedListType(*args, **kwargs):
     _list = list()
 
     def __init__(self, *args, **kwargs):
+      self._unique = kwargs.pop('unique', False)
       self._allowed_type = allowed_type
       self._list = list()
       if len(args):
         if isinstance(args[0], list):
           tmp = []
           for i in args[0]:
-            tmp.append(self.check(i))
+            if not self._unique or i not in tmp:
+              tmp.append(self.check(i))
           self._list.extend(tmp)
         else:
           tmp = self.check(args[0])
           self._list.append(tmp)
 
     def check(self, v):
+      # Short circuit uniqueness check
+      if self._unique and v in self._list:
+        raise ValueError("Values in this list must be unique.")
+
       passed = False
       count = 0
       for i in self._allowed_type:
@@ -446,16 +452,16 @@ def TypedListType(*args, **kwargs):
       del self._list[i]
 
     def __setitem__(self, i, v):
-      self.check(v)
-      self._list.insert(i, v)
+      self.insert(i, v)
 
     def insert(self, i, v):
       val = self.check(v)
       self._list.insert(i, val)
 
     def append(self, v):
-      val = self.check(v)
-      self._list.append(val)
+      if not self._unique or v not in self._list:
+        val = self.check(v)
+        self._list.append(val)
 
     def __str__(self):
       return str(self._list)
diff --git a/pyangbind/plugin/pybind.py b/pyangbind/plugin/pybind.py
index 98ef25e..3707c08 100644
--- a/pyangbind/plugin/pybind.py
+++ b/pyangbind/plugin/pybind.py
@@ -844,7 +844,7 @@ def get_children(ctx, fd, i_children, module, parent, path=str(),
         # TypedList (see lib.yangtypes) with a particular set of types allowed.
         class_str["name"] = "__%s" % (i["name"])
         class_str["type"] = "YANGDynClass"
-        class_str["arg"] = "base="
+        class_str["arg"] = "unique=True, base="
         if isinstance(i["type"]["native_type"][1], list):
           allowed_type = "["
           for subtype in i["type"]["native_type"][1]:
diff --git a/tox.ini b/tox.ini
index 51e59dc..d11d8c3 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = py{27,34,35,36,37,py2,py3},flake8
+envlist = py{27,34,35,36,37,py2},flake8
 skip_missing_interpreters = True
 
 [testenv]

Leaf-list stores multiple duplicate values
Hello,
I noticed in [RFC 6020 section 7.7 for leaf-list](https://tools.ietf.org/html/rfc6020#section-7.7) that there is a requirement on leaf-list which we do not follow in pyangbind.

`The values in a leaf-list MUST be unique.`

### Example:
Given the following yang model:
```yang
module test {
    namespace "http://foo/bar/test/1.0";
    prefix test;
    leaf-list my-leaf-list {
        type string;
    }
}
```
#### Expected
```python
>>> from test import test
>>> from pyangbind.lib.xpathhelper import YANGPathHelper
>>>
>>> graph = test(ph=YANGPathHelper())
>>>
>>> graph.my_leaf_list = ['foo', 'foo']
>>> graph.get()
{'my-leaf-list': [u'foo']}
```
#### Actual
```python
>>> graph.get()
{'my-leaf-list': [u'foo', u'foo']}
```

I think the leaf-list structure might need to resemble a set instead of a list, unless I misunderstood the rfc.
diff --git a/tests/leaf-list/run.py b/tests/leaf-list/run.py
index 331167b..f84c6cf 100755
--- a/tests/leaf-list/run.py
+++ b/tests/leaf-list/run.py
@@ -16,22 +16,21 @@ class LeafListTests(PyangBindTestCase):
     self.leaflist_obj = self.bindings.leaflist()
 
   def test_container_exists(self):
-    self.assertTrue(hasattr(self.leaflist_obj, "container"), "Base container is missing.")
+    self.assertTrue(hasattr(self.leaflist_obj, "container"))
 
   def test_leaflist_exists(self):
-    self.assertTrue(hasattr(self.leaflist_obj.container, "leaflist"), "Leaf-list instance is missing.")
+    self.assertTrue(hasattr(self.leaflist_obj.container, "leaflist"))
 
   def test_leaflist_length_is_zero(self):
-    self.assertEqual(len(self.leaflist_obj.container.leaflist), 0, "Length of leaflist was not zero.")
+    self.assertEqual(len(self.leaflist_obj.container.leaflist), 0)
 
   def test_append_to_leaflist(self):
     self.leaflist_obj.container.leaflist.append("itemOne")
-    self.assertEqual(len(self.leaflist_obj.container.leaflist), 1, "Did not successfully append string to list.")
+    self.assertEqual(len(self.leaflist_obj.container.leaflist), 1)
 
   def test_retrieve_leaflist_item_value(self):
     self.leaflist_obj.container.leaflist.append("itemOne")
-    self.assertEqual(self.leaflist_obj.container.leaflist[0], "itemOne",
-      "Cannot successfully address an item from the list.")
+    self.assertEqual(self.leaflist_obj.container.leaflist[0], "itemOne")
 
   def test_append_int_to_string_leaflist(self):
     with self.assertRaises(ValueError):
@@ -41,14 +40,14 @@ class LeafListTests(PyangBindTestCase):
     self.leaflist_obj.container.leaflist.append("itemOne")
     self.leaflist_obj.container.leaflist.append("itemTwo")
 
-    self.assertEqual(self.leaflist_obj.container.leaflist[1], "itemTwo", "getitem did not return the correct value.")
+    self.assertEqual(self.leaflist_obj.container.leaflist[1], "itemTwo")
 
   def test_setitem(self):
     self.leaflist_obj.container.leaflist.append("itemOne")
     self.leaflist_obj.container.leaflist.append("itemTwo")
     self.leaflist_obj.container.leaflist[1] = "indexOne"
 
-    self.assertEqual(self.leaflist_obj.container.leaflist[1], "indexOne", "setitem did not set the correct node.")
+    self.assertEqual(self.leaflist_obj.container.leaflist[1], "indexOne")
 
   def test_insert(self):
     self.leaflist_obj.container.leaflist.append("itemOne")
@@ -56,7 +55,7 @@ class LeafListTests(PyangBindTestCase):
     self.leaflist_obj.container.leaflist[1] = "indexOne"
     self.leaflist_obj.container.leaflist.insert(0, "indexZero")
 
-    self.assertEqual(self.leaflist_obj.container.leaflist[0], "indexZero", "Incorrectly set index 0 value")
+    self.assertEqual(self.leaflist_obj.container.leaflist[0], "indexZero")
 
   def test_leaflist_grows_from_various_modification_methods(self):
     self.leaflist_obj.container.leaflist.append("itemOne")
@@ -64,7 +63,7 @@ class LeafListTests(PyangBindTestCase):
     self.leaflist_obj.container.leaflist[1] = "indexOne"
     self.leaflist_obj.container.leaflist.insert(0, "indexZero")
 
-    self.assertEqual(len(self.leaflist_obj.container.leaflist), 4, "List item was not added by insert()")
+    self.assertEqual(len(self.leaflist_obj.container.leaflist), 4)
 
   def test_delete_item_from_leaflist(self):
     self.leaflist_obj.container.leaflist.append("itemOne")
@@ -74,7 +73,7 @@ class LeafListTests(PyangBindTestCase):
 
     del self.leaflist_obj.container.leaflist[0]
 
-    self.assertEqual(len(self.leaflist_obj.container.leaflist), 3, "List item not successfully removed by delitem")
+    self.assertEqual(len(self.leaflist_obj.container.leaflist), 3)
 
   def test_get_full_leaflist(self):
     self.leaflist_obj.container.leaflist.append("itemOne")
@@ -87,15 +86,13 @@ class LeafListTests(PyangBindTestCase):
       self.leaflist_obj.get(),
       {'container': {'leaflist': ['itemOne', 'indexOne', 'itemTwo'],
                      'listtwo': [],
-                     'listthree': []}},
-      "get did not correctly return the dictionary"
+                     'listthree': []}}
     )
 
   def test_leaflist_assignment(self):
     self.leaflist_obj.container.leaflist = ["itemOne", "itemTwo"]
 
-    self.assertEqual(self.leaflist_obj.container.leaflist, ["itemOne", "itemTwo"],
-      "Leaflist assignment did not function correctly")
+    self.assertEqual(self.leaflist_obj.container.leaflist, ["itemOne", "itemTwo"])
 
   def test_leaflist_assignment_of_wrong_type(self):
     with self.assertRaises(ValueError):
@@ -103,7 +100,7 @@ class LeafListTests(PyangBindTestCase):
 
   def test_restricted_string(self):
     self.leaflist_obj.container.listtwo.append("a-valid-string")
-    self.assertEqual(len(self.leaflist_obj.container.listtwo), 1, "Restricted lefalist did not function correctly.")
+    self.assertEqual(len(self.leaflist_obj.container.listtwo), 1)
 
   def test_restricted_string_invalid_value(self):
     with self.assertRaises(ValueError):
@@ -117,8 +114,23 @@ class LeafListTests(PyangBindTestCase):
           self.leaflist_obj.container.listthree.append(pair[0])
         except ValueError:
           allowed = False
-        self.assertEqual(allowed, pair[1], "leaf-list of union type had invalid result (%s != %s for %s)" %
-          (allowed, pair[1], pair[0]))
+        self.assertEqual(allowed, pair[1])
+
+  def test_leaf_lists_are_unique_after_assignment(self):
+    self.leaflist_obj.container.leaflist = ['foo', 'bar', 'foo']
+    self.assertEqual(self.leaflist_obj.container.get(filter=True), {'leaflist': ['foo', 'bar']})
+
+  def test_leaf_lists_are_unique_after_append(self):
+    self.leaflist_obj.container.leaflist.append('foo')
+    self.leaflist_obj.container.leaflist.append('bar')
+    self.leaflist_obj.container.leaflist.append('foo')
+    self.assertEqual(self.leaflist_obj.container.get(filter=True), {'leaflist': ['foo', 'bar']})
+
+  def test_leaf_lists_insert_non_unique_value_raises_keyerror(self):
+    self.leaflist_obj.container.leaflist[0] = 'foo'
+    self.leaflist_obj.container.leaflist[1] = 'bar'
+    with self.assertRaises(ValueError):
+      self.leaflist_obj.container.leaflist[2] = 'foo'
 
 
 if __name__ == '__main__':

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest flake8 requests
apt-get update apt-get install -y gcc
3.9
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
bitarray==3.3.0
certifi==2025.1.31
charset-normalizer==3.4.1
enum34==1.1.10
exceptiongroup==1.2.2
flake8==7.2.0
idna==3.10
iniconfig==2.1.0
lxml==5.3.1
mccabe==0.7.0
packaging==24.2
pluggy==1.5.0
pyang==2.6.1
-e git+https://github.com/robshakir/pyangbind.git@a3694e5434ba841016a737fc2d2373337d0c583e#egg=pyangbind
pycodestyle==2.13.0
pyflakes==3.3.1
pytest==8.3.5
regex==2024.11.6
requests==2.32.3
six==1.17.0
tomli==2.2.1
urllib3==2.3.0

name: pyangbind
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - bitarray==3.3.0
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - enum34==1.1.10
      - exceptiongroup==1.2.2
      - flake8==7.2.0
      - idna==3.10
      - iniconfig==2.1.0
      - lxml==5.3.1
      - mccabe==0.7.0
      - packaging==24.2
      - pluggy==1.5.0
      - pyang==2.6.1
      - pycodestyle==2.13.0
      - pyflakes==3.3.1
      - pytest==8.3.5
      - regex==2024.11.6
      - requests==2.32.3
      - six==1.17.0
      - tomli==2.2.1
      - urllib3==2.3.0
prefix: /opt/conda/envs/pyangbind

tests/leaf-list/run.py::LeafListTests::test_leaf_lists_are_unique_after_append tests/leaf-list/run.py::LeafListTests::test_leaf_lists_are_unique_after_assignment tests/leaf-list/run.py::LeafListTests::test_leaf_lists_insert_non_unique_value_raises_keyerror
tests/leaf-list/run.py::LeafListTests::test_append_int_to_string_leaflist tests/leaf-list/run.py::LeafListTests::test_append_to_leaflist tests/leaf-list/run.py::LeafListTests::test_container_exists tests/leaf-list/run.py::LeafListTests::test_delete_item_from_leaflist tests/leaf-list/run.py::LeafListTests::test_get_full_leaflist tests/leaf-list/run.py::LeafListTests::test_getitem tests/leaf-list/run.py::LeafListTests::test_insert tests/leaf-list/run.py::LeafListTests::test_leaflist_assignment tests/leaf-list/run.py::LeafListTests::test_leaflist_assignment_of_wrong_type tests/leaf-list/run.py::LeafListTests::test_leaflist_exists tests/leaf-list/run.py::LeafListTests::test_leaflist_grows_from_various_modification_methods tests/leaf-list/run.py::LeafListTests::test_leaflist_length_is_zero tests/leaf-list/run.py::LeafListTests::test_restricted_string tests/leaf-list/run.py::LeafListTests::test_restricted_string_invalid_value tests/leaf-list/run.py::LeafListTests::test_retrieve_leaflist_item_value tests/leaf-list/run.py::LeafListTests::test_setitem tests/leaf-list/run.py::LeafListTests::test_union_type
pyangbind/plugin/pybind.py tox.ini pyangbind/lib/yangtypes.py
pyangbind/plugin/pybind.py tox.ini pyangbind/lib/yangtypes.py