Skip to content

Commit

Permalink
v1.3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
wsmith323 committed May 25, 2020
1 parent c4757d7 commit 8837a7e
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 57 deletions.
File renamed without changes.
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include LICENSE.txt
include frozenordereddict/VERSION.txt
include release_notes.md
23 changes: 12 additions & 11 deletions README.rst → README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
FrozenOrderedDict
=================
# FrozenOrderedDict

An immutable wrapper around an OrderedDict.

FrozenOrderedDict was inspired by https://pypi.python.org/pypi/frozendict/
(and borrows some code from it). With regards to immutability, it
solves the same problems:

- Because dictionaries are mutable, they are not hashable and
- Because dictionaries are mutable, they are not hashable and
cannot be used in sets or as dictionary keys.
- Nasty bugs can and do occur when mutable data structures are
- Nasty bugs can and do occur when mutable data structures are
passed around.

It can be initialized just like a dict or OrderedDict. However, be
Expand All @@ -27,10 +26,12 @@ instance must be created. The easiest way to do that is by
calling the `.copy()` method. It will return a new instance of
FrozenOrderedDict initialized using the following steps:

1. A copy of the wrapped OrderedDict instance will be created.
2. If any arguments or keyword arguments are passed to the `.copy()`
method, they will be used to create another OrderedDict
instance, which will then be used to update the copy made in
step #1.
3. Finally, `self.__class__()` will be called, passing the copy as
the only argument.
1. A copy of the wrapped OrderedDict instance will be created.

1. If any arguments or keyword arguments are passed to the
`.copy()` method, they will be used to create another OrderedDict
instance, which will then be used to update the copy made in
step #1.

1. Finally, `self.__class__()` will be called, passing the copy as
the only argument.
1 change: 1 addition & 0 deletions frozenordereddict/VERSION.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.3.1
16 changes: 13 additions & 3 deletions frozenordereddict/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@

from collections import Mapping

try:
reduce
except NameError:
from functools import reduce

try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict
from functools import reduce

import operator
import os

with open(os.path.join(os.path.dirname(__file__), 'VERSION.txt')) as f:
__version__ = f.read().strip()


class FrozenOrderedDict(Mapping):
Expand All @@ -28,12 +38,12 @@ def __len__(self):

def __hash__(self):
if self.__hash is None:
self.__hash = reduce(operator.xor, map(hash, self.iteritems()), 0)
self.__hash = reduce(operator.xor, map(hash, self.__dict.items()), 0)

return self.__hash

def __repr__(self):
return '{}({!r})'.format(self.__class__.__name__, self.items())
return '{}({!r})'.format(self.__class__.__name__, self.__dict.items())

def copy(self, *args, **kwargs):
new_dict = self.__dict.copy()
Expand Down
37 changes: 37 additions & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

# frozenordereddict

## Release notes

### 1.3.1
* Add missing VERSION.txt to MANIFEST.in.

### 1.3.0
* Fix recursion in __repr__().
* Fix NameError for reduce() in __hash__() under Python 3.
* Fix tests under Python 3.
* Move README and release_notes to markdown.
* Fix MANIFEST.in to include LICENSE and release_notes.
* Add classifiers to setup().

### 1.2.0
* Change __repr__ to be the same format as OrderedDict.

### 1.1.1
* Fix (reverse) order of release notes.
* Minor format change in README.

### 1.1.0
* Allow keyword arguments for __init__() and copy().
* Add documentation to README.

### 1.0.1
* Minor refactor.

### 1.0.0
* Refactor, removing frozendict dependency.
* Add doc strings.
* Add tests.

### 0.1.0
* Initial release.
31 changes: 0 additions & 31 deletions release_notes.rst

This file was deleted.

17 changes: 10 additions & 7 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@

from setuptools import setup, find_packages

__version__ = "1.2.0"

def file_read(filename):
filepath = os.path.join(os.path.dirname(__file__), filename)
with open(filepath) as flo:
return flo.read()
with open(os.path.join(os.path.dirname(__file__), "frozenordereddict", 'VERSION.txt')) as f:
__version__ = f.read().strip()

setup(
name = "frozenordereddict",
Expand All @@ -17,9 +13,16 @@ def file_read(filename):
author = "Warren A. Smith",
author_email = "[email protected]",
description = "Frozen OrderedDict.",
long_description = file_read("README.rst"),
long_description = "An immutable wrapper around an OrderedDict",
long_description_content_type = "text/plain",
license = "MIT",
keywords = "ordereddict frozendict frozenordereddict orderedfrozendict ordered frozen dict",
url = "https://github.com/wsmith323/frozenordereddict",
test_suite = "tests",
classifiers = [
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
],
)
10 changes: 5 additions & 5 deletions tests/test_frozenordereddict.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ class TestFrozenOrderedDict(TestCase):

def test_init_from_items(self):
fod = FrozenOrderedDict(self.ITEMS_1)
self.assertEqual(list(self.ITEMS_1), fod.items())
self.assertEqual(list(self.ITEMS_1), list(fod.items()))

def test_init_from_ordereddict(self):
fod = FrozenOrderedDict(self.ODICT_1)
self.assertEqual(list(self.ITEMS_1), fod.items())
self.assertEqual(list(self.ITEMS_1), list(fod.items()))

def test_setitem(self):
def doit():
Expand Down Expand Up @@ -54,21 +54,21 @@ def test_copy_tuple_items(self):
fod2 = fod1.copy(self.ITEMS_2)

self.assertNotEqual(id(fod1), id(fod2))
self.assertEqual(fod1.items() + list(self.ITEMS_2), fod2.items())
self.assertEqual(list(fod1.items()) + list(self.ITEMS_2), list(fod2.items()))

def test_copy_ordereddict_items(self):
fod1 = FrozenOrderedDict(self.ITEMS_1)
fod2 = fod1.copy(self.ODICT_2)

self.assertNotEqual(id(fod1), id(fod2))
self.assertEqual(fod1.items() + list(self.ITEMS_2), fod2.items())
self.assertEqual(list(fod1.items()) + list(self.ITEMS_2), list(fod2.items()))

def test_copy_kwargs(self):
fod1 = FrozenOrderedDict(self.ITEMS_1)
fod2 = fod1.copy(**self.ODICT_2)

self.assertNotEqual(id(fod1), id(fod2))
self.assertEqual(dict(fod1.items() + self.ODICT_2.items()), fod2)
self.assertEqual(dict(list(fod1.items()) + list(self.ODICT_2.items())), fod2)



Expand Down

0 comments on commit 8837a7e

Please sign in to comment.