Repository: chimpler/pyhocon

Issue:
NoneValue object in parse result of "a=null" in PyPy
In PyPy, parse result of "a=null" has a NoneValue object which is wrong:
```
Python 2.7.12 (aff251e543859ce4508159dd9f1a82a2f553de00, Nov 25 2016, 00:02:08)
[PyPy 5.6.0 with GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>> from pyhocon import ConfigFactory
>>>> ConfigFactory.parse_string('a=null')
ConfigTree([('a', <pyhocon.config_tree.NoneValue object at 0x00000001116cbe18>)])
```

In CPython, it's ok:

```
Python 2.7.13 (default, Dec 18 2016, 07:03:39) 
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyhocon import ConfigFactory
>>> ConfigFactory.parse_string('a=null')
ConfigTree([('a', None)])
```

Versions:
* pyhocon==0.3.35
* pyparsing==2.1.10
* PyPy and CPython versions are above.

Discussion:

Patch:
diff --git a/pyhocon/config_tree.py b/pyhocon/config_tree.py
index 1492793..c39a977 100644
--- a/pyhocon/config_tree.py
+++ b/pyhocon/config_tree.py
@@ -1,7 +1,6 @@
 from collections import OrderedDict
 from pyparsing import lineno
 from pyparsing import col
-
 try:
     basestring
 except NameError:  # pragma: no cover
@@ -364,6 +363,14 @@ class ConfigTree(OrderedDict):
             raise KeyError(item)
         return val
 
+    try:
+        from collections import _OrderedDictItemsView
+    except ImportError:  # pragma: nocover
+        pass
+    else:
+        def items(self):  # pragma: nocover
+            return self._OrderedDictItemsView(self)
+
     def __getattr__(self, item):
         val = self.get(item, NonExistentKey)
         if val is NonExistentKey:


Test patch:
diff --git a/tests/test_config_tree.py b/tests/test_config_tree.py
index fbdee7b..1435cff 100644
--- a/tests/test_config_tree.py
+++ b/tests/test_config_tree.py
@@ -1,6 +1,6 @@
 import pytest
 from collections import OrderedDict
-from pyhocon.config_tree import ConfigTree
+from pyhocon.config_tree import ConfigTree, NoneValue
 from pyhocon.exceptions import (
     ConfigMissingException, ConfigWrongTypeException, ConfigException)
 
@@ -70,6 +70,11 @@ class TestConfigTree(object):
         config_tree.put("a.b.c", None)
         assert config_tree.get("a.b.c") is None
 
+    def test_config_tree_null_items(self):
+        config_tree = ConfigTree()
+        config_tree.put("a", NoneValue())
+        assert list(config_tree.items()) == [("a", None)]
+
     def test_getters(self):
         config_tree = ConfigTree()
         config_tree.put("int", 5)