Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions odictliteral.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
try:
from collections import OrderedDict
except:
except ImportError:
from ordereddict import OrderedDict

try:
from reprlib import recursive_repr
except:
except ImportError:
# don't cope with recursive repr calls in py2
def recursive_repr(fillvalue='...'): return (lambda f: f)
def recursive_repr(fillvalue='...'):
return (lambda f: f)

try:
from collections.abc import Iterable
except:
Iterable = tuple
from collections import Iterable
except ImportError:
try:
from collections.abc import Iterable
except ImportError:
Iterable = tuple


__all__ = ["odict"]
__version__ = '1.0.0'
__version__ = '1.0.1'


class odictType(type):
syntax_error = SyntaxError("Allowed syntax: odict[<k>: <v>(, <k>: <v>...)]")
Expand All @@ -25,18 +31,25 @@ def __getitem__(self, keys):
keys = (keys,)
if not isinstance(keys, Iterable):
raise self.syntax_error

od = self()
for k in keys:
if not isinstance(k, slice) or k.step is not None:
raise self.syntax_error

od[k.start] = k.stop

return od


@recursive_repr(fillvalue="odict[...]")
def odict_repr(self):
if len(self) == 0:
if not self:
return "odict()"
else:
return "odict[%s]" % (", ".join("%r: %r" % (k,v) for k,v in self.items()),)

return "odict[%s]" % (", ".join(
"%r: %r" % (k, v)
for k, v in self.items()
),)

odict = odictType(str('odict'), (OrderedDict,), {"__repr__": odict_repr})
50 changes: 29 additions & 21 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
#!/usr/bin/env python
import re
import codecs
import os.path

from setuptools import setup, find_packages

import codecs, os.path, re
from setuptools import setup

here = os.path.abspath(os.path.dirname(__file__))

# Read the version number from a source file.
# Why read it, and not import?
# see https://groups.google.com/d/topic/pypa-dev/0PkjVpcxTzQ/discussion

def find_version(*file_paths):
"""
Read the version number from a source file.
Why read it, and not import?
see https://groups.google.com/d/topic/pypa-dev/0PkjVpcxTzQ/discussion
"""
# Open in Latin-1 so that we avoid encoding errors.
# Use codecs.open for Python 2 compatibility
with codecs.open(os.path.join(here, *file_paths), 'r', 'latin1') as f:
Expand All @@ -23,27 +27,31 @@ def find_version(*file_paths):
return version_match.group(1)
raise RuntimeError("Unable to find version string.")


with codecs.open('README.rst', encoding='utf-8') as f:
long_description = f.read()


setup(
name = 'odictliteral',
version = find_version('odictliteral.py'),
description = 'A tidier way of coding literal OrderedDicts',
long_description = long_description,
py_modules=['odictliteral'],
name='odictliteral',
version=find_version('odictliteral.py'),
description='A tidier way of coding literal OrderedDicts',
long_description=long_description,
py_modules=['odictliteral'],

url='https://github.com/ajtowns/odictliteral',

url = 'https://github.com/ajtowns/odictliteral',
author='Anthony Towns',
author_email='aj@erisian.com.au',

author = 'Anthony Towns',
author_email = 'aj@erisian.com.au',
license='MIT',

license = 'MIT',
classifiers=[
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3',
],

classifiers = [
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3',
],
tests_require=["pytest"],
)
62 changes: 62 additions & 0 deletions test_odictliteral.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# Interpreter version: python 2.7
#
# Imports =====================================================================
import pytest

from odictliteral import odict
from odictliteral import OrderedDict


# Tests =======================================================================
def test_odictType():
complex_dict = odict[
"another": odict[
"here": "more keys",
1: "hello"
],
"key": "val",
2: "numeric",
"aaa": "bbb"
]

complex_ordered_dict = OrderedDict([
["another", OrderedDict([
["here", "more keys"],
[1, "hello"]
])],
["key", "val"],
[2, "numeric"],
["aaa", "bbb"]
])

assert complex_dict == complex_ordered_dict

assert list(complex_dict.keys()) == ["another", "key", 2, "aaa"]


def test_constructor():
assert odict(fist=1) == odict["fist": 1]
assert odict([("fist", 1), ("second", 2)]) == odict["fist": 1, "second": 2]


def test_errors():
with pytest.raises(SyntaxError):
odict[1]

with pytest.raises(SyntaxError):
odict["hello"]

with pytest.raises(SyntaxError):
assert odict[["key", "val"]]

with pytest.raises(SyntaxError):
assert odict[("key", "val")]


def test_repr():
assert repr(odict()) == "odict()"
assert repr(odict["key": "val"]) == 'odict[key: val]'
assert repr(odict["k": "v", "x": "y"]) == 'odict[k: v, x: y]'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is wrong, the output should include quotes