Skip to content

Commit

Permalink
list
Browse files Browse the repository at this point in the history
  • Loading branch information
maccam912 committed Oct 17, 2022
1 parent 44fba42 commit 787d35f
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 7 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "add-only-dictionary"
version = "0.1.3"
version = "0.1.4"
description = "Add Only Dictionary"
authors = ["Matt Koski <[email protected]>"]
license = "MIT"
Expand Down
1 change: 1 addition & 0 deletions src/add_only_dictionary/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Add Only Dictionary."""

from add_only_dictionary.aodict import AODict as AODict
from add_only_dictionary.aolist import AOList as AOList
36 changes: 30 additions & 6 deletions src/add_only_dictionary/aodict.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,25 @@
from typing import Any
from typing import Dict

from add_only_dictionary.aolist import AOList


class AODict(Dict[Any, Any]):
"""AODict class."""

def __init__(self, d: dict[Any, Any] | None = None):
def __init__(self, d: dict[Any, Any] | None = None) -> None:
"""Create new AODict. If dict is given, convert it."""
if d is not None:
super().update(d)
self.init_load(d)

def init_load(self, d: dict[Any, Any]) -> None:
"""Insert each item from d into AODict.
Args:
d (dict[Any, Any]): dictionary to insert items from
"""
for k in d:
self.__setitem__(k, d[k])

def __setitem__(self, k: Any, v: Any) -> None:
"""Lets you add item to dict, but not if key exists.
Expand All @@ -24,8 +35,21 @@ def __setitem__(self, k: Any, v: Any) -> None:
v (Any): the value
"""
if k not in self.keys():
if not isinstance(v, dict):
super().__setitem__(k, v)
if isinstance(v, dict):
ao_d: AODict = AODict(v)
super().__setitem__(k, ao_d)

elif isinstance(v, list):
ao_l: AOList = AOList(v)
super().__setitem__(k, ao_l)

else:
ao_v: AODict = AODict(v)
super().__setitem__(k, ao_v)
super().__setitem__(k, v)

def __delitem__(self, k: Any) -> None:
"""Override the __delitem__ method, and prevent it.
Args:
k (Any): the key that would normally be removed
"""
pass
36 changes: 36 additions & 0 deletions src/add_only_dictionary/aolist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""class AODict."""
from __future__ import annotations

from typing import Any
from typing import List


try:
from typing_extensions import SupportsIndex
except ImportError:
from typing import SupportsIndex


class AOList(List[Any]):
"""AOList class."""

def __init__(self, initial_list: list[Any] | None = None):
"""Create new AOList. If list is given, convert it."""
if initial_list is not None:
super().extend(initial_list)

def __delitem__(self, key: Any) -> None:
"""No op on AOList."""
pass

def remove(self, item: Any) -> None:
"""No op on AOList."""
pass

def pop(self, idx: SupportsIndex = ...) -> Any:
"""No op on AOList."""
pass

def clear(self) -> None:
"""No op on AOList."""
pass
17 changes: 17 additions & 0 deletions tests/test_aodict.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@ def test_nested_dict() -> None:
assert ao["a"]["c"] == 3


def test_remove_attempt() -> None:
"""Trying to delete a key from a dict should fail."""
ao: AODict = AODict()
ao["a"] = 1
del ao["a"]
assert ao["a"] == 1


def test_list_methods() -> None:
"""Trying to delete a key from a dict should fail."""
ao: AODict = AODict({"a": [1, 2, 3]})
del ao["a"]
assert ao["a"] == [1, 2, 3]
ao["a"].pop()
assert ao["a"] == [1, 2, 3]


def test_json_dumps() -> None:
"""When using json.dumps on an AODict it should behave like regular dict."""
ao: AODict = AODict()
Expand Down
27 changes: 27 additions & 0 deletions tests/test_aolist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Tests for AOList."""
from add_only_dictionary import AOList


def check_invariants(ao: AOList) -> None:
"""Common checks that shoujld continue being true."""
assert ao[0] == 1
assert ao[-1] == 3
assert len(ao) == 3


def test_methods() -> None:
"""Test the four methods that would normally remove elements."""
ao: AOList = AOList([1, 2, 3])
check_invariants(ao)

del ao[0]
check_invariants(ao)

ao.remove(2)
check_invariants(ao)

ao.pop()
check_invariants(ao)

ao.clear()
check_invariants(ao)

0 comments on commit 787d35f

Please sign in to comment.