Hello community,

here is the log from the commit of package python-ordered-namespace for 
openSUSE:Factory checked in at 2019-07-23 22:40:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-ordered-namespace (Old)
 and      /work/SRC/openSUSE:Factory/.python-ordered-namespace.new.4126 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-ordered-namespace"

Tue Jul 23 22:40:51 2019 rev:5 rq:717901 version:2019.6.8

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-ordered-namespace/python-ordered-namespace.changes
        2019-06-06 18:16:17.932704010 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-ordered-namespace.new.4126/python-ordered-namespace.changes
      2019-07-23 22:40:55.454906835 +0200
@@ -1,0 +2,8 @@
+Tue Jul 23 13:40:19 UTC 2019 - Tomáš Chvátal <tchva...@suse.com>
+
+- Update to 2019.6.8:
+  * Jupyter/iPython pretty printing works even better than before. Everything 
lines up and is easier to read at a glance.
+  * Tab auto-completion now shows both class methods and data attribute. 
Previously it only showed data attributes.
+  * Full support for pickle serialization/deserialization.
+
+-------------------------------------------------------------------

Old:
----
  ordered_namespace-2018.6.26.tar.gz

New:
----
  ordered_namespace-2019.6.8.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-ordered-namespace.spec ++++++
--- /var/tmp/diff_new_pack.x51m1i/_old  2019-07-23 22:40:56.102906015 +0200
+++ /var/tmp/diff_new_pack.x51m1i/_new  2019-07-23 22:40:56.122905989 +0200
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-ordered-namespace
-Version:        2018.6.26
+Version:        2019.6.8
 Release:        0
 Summary:        Python namespace class
 License:        MIT

++++++ ordered_namespace-2018.6.26.tar.gz -> ordered_namespace-2019.6.8.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ordered_namespace-2018.6.26/PKG-INFO 
new/ordered_namespace-2019.6.8/PKG-INFO
--- old/ordered_namespace-2018.6.26/PKG-INFO    2018-06-27 01:54:24.000000000 
+0200
+++ new/ordered_namespace-2019.6.8/PKG-INFO     2019-06-09 05:57:42.000000000 
+0200
@@ -1,11 +1,11 @@
 Metadata-Version: 1.0
 Name: ordered_namespace
-Version: 2018.6.26
-Summary: An easy-to-use Python namespace class derived from OrderedDict, 
including tab-completion
+Version: 2019.6.8
+Summary: An easy-to-use Python namespace class derived from OrderedDict, 
includes tab-completion
 Home-page: https://github.com/who8mylunch/OrderedNamespace
 Author: Pierre V. Villeneuve
 Author-email: pierre.villene...@gmail.com
 License: MIT
 Description: UNKNOWN
-Keywords: namespace,ordereddict,structure
+Keywords: namespace,ordereddict,structure,dotdict,tab-completion
 Platform: UNKNOWN
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ordered_namespace-2018.6.26/README.md 
new/ordered_namespace-2019.6.8/README.md
--- old/ordered_namespace-2018.6.26/README.md   2017-07-18 04:03:52.000000000 
+0200
+++ new/ordered_namespace-2019.6.8/README.md    2019-06-08 23:05:09.000000000 
+0200
@@ -1,6 +1,6 @@
 # OrderedNamespace
 
-Namespaces are a great idea and this one is mine.
+Dot-accessible attributes and namespaces are great ideas and this one is mine.
 
 What's the big deal?  Python dicts are just fine, but in the Jupyter/IPython 
interactive environment I hate having to deal with brackets and quotes when 
using tab-based auto-completion to get a quick glance at the contents of an 
object.
 
@@ -68,4 +68,3 @@
 - http://ipython.readthedocs.io/en/stable/config/integrating.html
 - https://github.com/ipython/ipython/blob/master/IPython/lib/pretty.py
 - https://docs.python.org/3/library/functions.html#dir
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ordered_namespace-2018.6.26/ordered_namespace/core.py 
new/ordered_namespace-2019.6.8/ordered_namespace/core.py
--- old/ordered_namespace-2018.6.26/ordered_namespace/core.py   2018-06-27 
01:51:59.000000000 +0200
+++ new/ordered_namespace-2019.6.8/ordered_namespace/core.py    2019-06-09 
05:48:13.000000000 +0200
@@ -1,46 +1,48 @@
 from collections import OrderedDict, UserDict
 import re
 
+__all__ = ['Struct']
 
 
-
-def convert_to_struct(value):
+def safe_convert_to_struct(value, nested=False):
     """Convert the following to Structs:
        - dicts
        - list elements that are dicts
        - ???
 
-    This function is harmless to call on arbitrary variables.
+    This function is harmless to call on un-handled variables.
     """
     direct_converts = [dict, OrderedDict, UserDict]
     if type(value) in direct_converts:
         # Convert dict-like things to Struct
-        value = Struct(value)
+        value = Struct(value, nested=nested)
     elif isinstance(value, list):
         # Process list elements
-        value = [convert_to_struct(z) for z in value]
+        value = [safe_convert_to_struct(z, nested=nested) for z in value]
+    elif isinstance(value, tuple):
+        # Process list elements
+        value = tupe([safe_convert_to_struct(z, nested=nested) for z in value])
 
     # Done
     return value
 
 
 
-class Struct:
+class Struct():
     """Ordered namespace class
     """
 
     # Regular expression pattern for valid Python attributes
     # https://docs.python.org/3/reference/lexical_analysis.html#identifiers
-    # _valid_key_pattern = re.compile('[a-zA-Z_][a-zA-Z0-9_]*')
     _valid_key_pattern = re.compile('[a-zA-Z][a-zA-Z0-9_]*')
     _special_names = ['_odict']
     _repr_max_width = 13
 
-    def __init__(self, *args, **kwargs):
+    def __init__(self, *args, nested=False, **kwargs):
         """Ordered namespace class
         """
         self.__dict__['_odict'] = OrderedDict()
-
+        self.__dict__['_nested'] = nested
         self.update(*args, **kwargs)
 
     def update(self, *args, **kwargs):
@@ -48,6 +50,7 @@
         """
         d = {}
         d.update(*args, **kwargs)
+
         for key, value in d.items():
             self[key] = value
 
@@ -57,18 +60,22 @@
         attribute names (e.g. dict class instance methods).
         """
         if not isinstance(key, str):
+            # attributes must be a string
             return False
         elif hasattr({}, key):
+            # attributes cannot be same as existing dict method
             return False
         elif key in self._special_names:
+            # attributes cannot be same as pre-identified special names
             return False
         else:
+            # attributes must match valid key pattern
             return self._valid_key_pattern.match(key)
 
     def asdict(self):
         """Return a recursive dict representation of self
         """
-        d = dict(self._odict)
+        d = self._odict
 
         for k,v in d.items():
             if isinstance(v, Struct):
@@ -77,7 +84,7 @@
         return d
 
     #--------------------------------
-    # Expose a few standard dict methods
+    # Expose standard dict methods
     def items(self):
         return self._odict.items()
 
@@ -90,13 +97,16 @@
     def pop(self, key):
         return self._odict.pop(key)
 
+    def copy(self):
+        return self._odict.copy()
+
     #--------------------------------
     # Expose essential dict internal methods
     def __setattr__(self, key, value):
         """Set an item with dot-style access while testing for invalid names
         """
         if not self._valid_key(key):
-            raise AttributeError('Invalid attribute name: {}'.format(key))
+            raise AttributeError('Invalid key/attribute name: {}'.format(key))
 
         try:
             self[key] = value
@@ -105,20 +115,18 @@
 
     def __setitem__(self, key, value):
         if not self._valid_key(key):
-            raise KeyError('Invalid attribute name: {}'.format(key))
+            raise KeyError('Invalid key/attribute name: {}'.format(key))
 
-        value = convert_to_struct(value)
-        # if isinstance(value, dict) and key not in self._special_names:
-        #     # Convert dict to Struct
-        #     value = Struct(value)
-        # elif isinstance(value, list):
-        #     # Find elements to convert from dict to Struct
-        #     change = []
-        #     for k, v in enumerate(value):
-        #         if isinstance(v, dict):
-        #             change.append(k)
+        if self._nested:
+            self._odict[key] = safe_convert_to_struct(value, nested=True)
+        else:
+            self._odict[key] = value
+
+    def __getstate__(self):
+        return self.__dict__.copy()
 
-        self._odict[key] = value
+    def __setstate__(self, state):
+        self.__dict__.update(state)
 
     def __getattr__(self, key):
         return self._odict[key]
@@ -141,11 +149,6 @@
     def __contains__(self, key):
         return self._odict.__contains__(key)
 
-    def __dir__(self):
-        
"""http://ipython.readthedocs.io/en/stable/config/integrating.html#tab-completion
-        """
-        return self._odict.keys()
-
     def __eq__(self, other):
         return self._odict.__eq__(other)
 
@@ -153,13 +156,16 @@
         return self._odict.__ne__(other)
 
     def __repr__(self):
-        return self._odict.__repr__()
+        if self:
+            return '%s(%r)' % (self.__class__.__name__, self.items())
+        else:
+            return '%s()' % (self.__class__.__name__,)
 
-    # def _ipython_key_completions_(self):
-    #     
"""http://ipython.readthedocs.io/en/stable/config/integrating.html#tab-completion
-    #     """
-    #     print('sdfdsfdf')
-    #     return self.__dir__()
+    def __dir__(self):
+        
"""http://ipython.readthedocs.io/en/stable/config/integrating.html#tab-completion
+        https://amir.rachum.com/blog/2016/10/05/python-dynamic-attributes
+        """
+        return super().__dir__() + [str(k) for k in self._odict.keys()]
 
     def _repr_pretty_(self, p, cycle):
         """Derived from IPython's dict and sequence pretty printer functions,
@@ -168,28 +174,24 @@
         if cycle:
             p.text('{...}')
         else:
-            keys = self.keys()
+            delim_start = self.__class__.__name__ + '{'
+            delim_end = '}'
+
+            with p.group(indent=len(delim_start), open=delim_start, 
close=delim_end):
+                # Loop over items
+                for ix, (key, value) in p._enumerate(self.items()):
+                    p.break_()
+
+                    key_txt = '{:s}: '.format(key)
+                    L = len(key_txt)
+
+                    p.indentation += L
+                    p.text(key_txt)
+                    p.pretty(value)
+                    p.text(',')
+                    p.indentation -= L
 
-            if keys:
-                delim_start = '[{'
-                delim_end = '}]'
-
-                wid_max_max = self._repr_max_width
-                wid_max = max([len(k) for k in keys])
-                wid_max = min([wid_max, wid_max_max])
-                key_template = '{{:{:d}s}}: '.format(wid_max)
-
-                with p.group(len(delim_start), delim_start, delim_end):
-                    # Loop over item keys
-                    for idx, key in p._enumerate(keys):
-                        if idx:
-                            p.text(',')
-                            p.breakable()
-
-                        p.text(key_template.format(key))
-                        p.pretty(self[key])
-            else:
-                p.text('{}')
+                p.break_()
 
 #------------------------------------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ordered_namespace-2018.6.26/ordered_namespace.egg-info/PKG-INFO 
new/ordered_namespace-2019.6.8/ordered_namespace.egg-info/PKG-INFO
--- old/ordered_namespace-2018.6.26/ordered_namespace.egg-info/PKG-INFO 
2018-06-27 01:54:24.000000000 +0200
+++ new/ordered_namespace-2019.6.8/ordered_namespace.egg-info/PKG-INFO  
2019-06-09 05:57:42.000000000 +0200
@@ -1,11 +1,11 @@
 Metadata-Version: 1.0
 Name: ordered-namespace
-Version: 2018.6.26
-Summary: An easy-to-use Python namespace class derived from OrderedDict, 
including tab-completion
+Version: 2019.6.8
+Summary: An easy-to-use Python namespace class derived from OrderedDict, 
includes tab-completion
 Home-page: https://github.com/who8mylunch/OrderedNamespace
 Author: Pierre V. Villeneuve
 Author-email: pierre.villene...@gmail.com
 License: MIT
 Description: UNKNOWN
-Keywords: namespace,ordereddict,structure
+Keywords: namespace,ordereddict,structure,dotdict,tab-completion
 Platform: UNKNOWN
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ordered_namespace-2018.6.26/setup.py 
new/ordered_namespace-2019.6.8/setup.py
--- old/ordered_namespace-2018.6.26/setup.py    2018-06-27 01:43:06.000000000 
+0200
+++ new/ordered_namespace-2019.6.8/setup.py     2019-06-09 05:57:37.000000000 
+0200
@@ -1,7 +1,7 @@
 
 from setuptools import setup, find_packages
 
-version = '2018.6.26'
+version = '2019.6.8'
 
 setup(
     name='ordered_namespace',
@@ -11,8 +11,8 @@
     version=version,
     author='Pierre V. Villeneuve',
     author_email='pierre.villene...@gmail.com',
-    description='An easy-to-use Python namespace class derived from 
OrderedDict, including tab-completion',
+    description='An easy-to-use Python namespace class derived from 
OrderedDict, includes tab-completion',
     url='https://github.com/who8mylunch/OrderedNamespace',
     license='MIT',
-    keywords=['namespace', 'ordereddict', 'structure'],
+    keywords=['namespace', 'ordereddict', 'structure', 'dotdict', 
'tab-completion'],
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ordered_namespace-2018.6.26/test/test.py 
new/ordered_namespace-2019.6.8/test/test.py
--- old/ordered_namespace-2018.6.26/test/test.py        2018-06-27 
01:42:15.000000000 +0200
+++ new/ordered_namespace-2019.6.8/test/test.py 2019-06-09 05:42:22.000000000 
+0200
@@ -2,6 +2,8 @@
 from __future__ import division, print_function, unicode_literals, 
absolute_import
 
 import unittest
+import pickle
+from collections import OrderedDict
 
 try:
     import context
@@ -100,20 +102,40 @@
 
         self.assertTrue(keys_test_1 == keys_test_2[::-1])
 
-    def test_nested_dict_converted(self):
+    def test_nested_flag_set(self):
+        info = ons.Struct(nested=True)
+        self.assertTrue(info.__dict__['_nested'])
+
+    def test_nested_flag_not_set(self):
+        info = ons.Struct(nested=False)
+        self.assertFalse(info.__dict__['_nested'])
+
+    def test_nested_flag_default_not_set(self):
         info = ons.Struct()
+        self.assertFalse(info.__dict__['_nested'])
+
+    def test_nested_dict_converted(self):
+        info = ons.Struct(nested=True)
 
         nuts = {'a': [1, 2], 'X': 'hello'}
         corn = {'b': [6, 9], 'Y': 'bye'}
 
         info.AA = nuts
-        info.AA.BB = corn
-
         self.assertTrue(type(info.AA) == ons.Struct)
+
+        info.AA.BB = corn
         self.assertTrue(type(info.AA.BB) == ons.Struct)
 
+    def test_not_nested_dict_converted(self):
+        info = ons.Struct(nested=False)
+
+        nuts = {'a': [1, 2], 'X': 'hello'}
+
+        info.AA = nuts
+        self.assertTrue(type(info.AA) == dict)
+
     def test_nested_dict_update(self):
-        info = ons.Struct()
+        info = ons.Struct(nested=True)
 
         nuts = {'a': [1, 2], 'X': 'hello'}
         corn = {'b': [6, 9], 'Y': 'bye', 'm': nuts}
@@ -126,32 +148,29 @@
         self.assertTrue(type(info.CC.n.m) == ons.Struct)
 
     def test_nested_dict_define(self):
-
         nuts = {'a': [1, 2], 'X': 'hello'}
         corn = {'b': [6, 9], 'Y': 'bye', 'm': nuts}
         yikes = {'c': [6, 9], 'Z': 'hello', 'n': corn}
 
-        info = ons.Struct(yikes)
+        info = ons.Struct(yikes, nested=True)
 
-        # print(yikes.n.m)
-        # print(type(yikes.n.m))
+        self.assertTrue(type(info.n) == ons.Struct)
         self.assertTrue(type(info.n.m) == ons.Struct)
 
     def test_nested_dict_list(self):
-
         nuts = {'a': [1, 2], 'X': 'hello'}
         corn = {'b': [6, 9], 'Y': 'bye'}
         yikes = {'c': [6, 9], 'Z': 'hello'}
 
         stuff = [nuts, corn, yikes]
 
-        info = ons.Struct()
+        info = ons.Struct(nested=True)
         info.S = stuff
 
         self.assertTrue(type(info.S[0]) == ons.Struct)
 
     def test_as_dict(self):
-        info = ons.Struct()
+        info = ons.Struct(nested=True)
 
         nuts = {'a': [1, 2], 'X': 'hello'}
         corn = {'b': [6, 9], 'Y': 'bye'}
@@ -161,10 +180,53 @@
 
         info = info.asdict()
 
-        self.assertTrue(type(info) == dict)
-        self.assertTrue(type(info['AA']) == dict)
-        self.assertTrue(type(info['AA']['BB']) == dict)
+        self.assertTrue(type(info) == OrderedDict)
+        self.assertTrue(type(info['AA']) == OrderedDict)
+        self.assertTrue(type(info['AA']['BB']) == OrderedDict)
+
+
+
+class TestFancy(unittest.TestCase):
+    # def setUp(self):
+    #     pass
+
+    # def tearDown(self):
+    #     pass
+
+    def test_does_it_pickle(self):
+        info = ons.Struct()
+        info.A = [1, 2, 3, 4, 'A']
+
+        z = pickle.dumps(info)
+
+    def test_does_it_unpickle(self):
+        info = ons.Struct()
+        info.A = [1, 2, 3, 4, 'WW']
+
+        z = pickle.dumps(info)
+        anfo = pickle.loads(z)
+
+    def test_pickle_unpickle_keys(self):
+        info = ons.Struct()
+        info.A = [1, 2, 3, 4, 'WW']
+
+        z = pickle.dumps(info)
+        anfo = pickle.loads(z)
+
+        for k, v in info.items():
+            self.assertTrue(k in anfo)
+
+    def test_pickle_unpickle_value(self):
+        info = ons.Struct()
+        info.A = [1, 2, 3, 4, 'WW']
+        info.SS = 4
+        info.WWW = {'d': [1,2,3]}
+
+        z = pickle.dumps(info)
+        anfo = pickle.loads(z)
 
+        for k, v in info.items():
+            self.assertTrue(v == anfo[k])
 
 #------------------------------------------------
 


Reply via email to