Skip to content

Commit

Permalink
fixing mypy and pylint errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
tybruno committed Jun 20, 2024
1 parent d933f0d commit 2020ca7
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 26 deletions.
8 changes: 8 additions & 0 deletions modifiable_items_dictionary/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
"""modifiable_items_dictionary package
Subpackages:
- modifiable_items_dictionary: Contains the ModifiableItemsDict and
ModifiableItemsAttrDict classes.
- modifiable_items_attribute_dictionary: Contains the ModifiableItemsAttrDict
class.
"""
from modifiable_items_dictionary.modifiable_items_dictionary import (
ModifiableItemsDict,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
This module was heavily inspired by Raymond Hettinger's class.
[1] Hettinger, R. (2023). (Advanced) Python For Engineers: Part 3.
"""
from typing import Any

from modifiable_items_dictionary.modifiable_items_dictionary import (
ModifiableItemsDict,
)
from typing import Any


class ModifiableItemsAttrDict(ModifiableItemsDict):
Expand All @@ -28,6 +29,7 @@ class ModifiableItemsAttrDict(ModifiableItemsDict):
items. This means that in addition to the standard dictionary access
syntax (dict["key"]), you can also use attribute syntax (dict.key).
"""

__slots__ = ()

def __getattr__(self, name: str) -> Any:
Expand All @@ -50,11 +52,11 @@ def __getattr__(self, name: str) -> Any:
"""
try:
value = self[name]
except KeyError:
except KeyError as error:
raise AttributeError(
f"'{self.__class__.__name__}' object has no attribute "
f"'{name}'."
)
) from error
return value

def __setattr__(self, name: str, value: Any) -> None:
Expand Down
65 changes: 43 additions & 22 deletions modifiable_items_dictionary/modifiable_items_dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
[1] Hettinger, R. (2023). (Advanced) Python For Engineers: Part 3.
"""
import contextlib
import multiprocessing.pool
from typing import (
Any,
Callable,
Expand All @@ -23,8 +22,10 @@
TypeVar,
Union,
overload,
Protocol,
)


# Sentinel
NO_DEFAULT = object()

Expand All @@ -33,12 +34,12 @@
Self = TypeVar('Self', bound='ModifiableItemsDict')

Key = Hashable
_KT = TypeVar('_KT')
_VT_co = TypeVar('_VT_co', covariant=True)
Value = Any
MappingCallable = Union[
map,
multiprocessing.pool.ThreadPool.map,
multiprocessing.pool.ThreadPool.imap,
multiprocessing.pool.ThreadPool.imap_unordered,
Callable,
]
KeyCallable = Callable[[Any], Key]
ValueCallable = Callable[[Any], Value]
Expand All @@ -47,6 +48,16 @@
Union[Self, ValueCallable, Iterable[ValueCallable], None]
]

# Protocol
class SupportsKeysAndGetItem(Protocol[_KT, _VT_co]):
"""Protocol for objects that support keys and getitem."""

def keys(self) -> Iterable[_KT]:
"""Return an iterable of the container's keys."""

def __getitem__(self, __key: _KT) -> _VT_co:
"""Return the value for a key."""


class ModifiableItemsDict(dict):
"""Dictionary class that can modify __key and v at runtime.
Expand Down Expand Up @@ -75,7 +86,6 @@ class ModifiableItemsDict(dict):

__slots__ = ()

# TODO: Add validators
_key_modifiers: KeyModifiers = None
_value_modifiers: ValueModifiers = None
_map_function: MappingCallable = map
Expand Down Expand Up @@ -189,12 +199,9 @@ def _create_modified_mapping(self, iterable):
Dictionary with the modified keys and values.
"""

new_mapping: Mapping[Key, Value] = {
key: value
for key, value in self._map_function(
self._modify_key_and_item, iterable
)
}
new_mapping = dict(
self._map_function(self._modify_key_and_item, iterable)
)

return new_mapping

Expand Down Expand Up @@ -223,7 +230,17 @@ def fromkeys(
cls,
__iterable: Iterable[Key],
__value: Optional[Union[Value, None]] = None,
) -> Self:
):
"""Create a new dictionary with keys from iterable and values set to
value.
Args:
__iterable: Iterable of keys.
__value: Value to set for each key. Default is None.
Returns:
New dictionary with keys from iterable and values set to value.
"""
return cls(dict.fromkeys(__iterable, __value))

@overload
Expand Down Expand Up @@ -252,7 +269,7 @@ def __init__(
if kwargs:
kwargs = self._iterable_to_modified_dict(kwargs)

dict.__init__(self, iterable or dict(), **kwargs)
dict.__init__(self, iterable or {}, **kwargs)

def __getitem__(self, k: Key) -> Any:
k = self._modify_key(k)
Expand All @@ -272,7 +289,7 @@ def __contains__(self, __item: Value) -> bool:
_is_in: bool = dict.__contains__(self, __item)
return _is_in

def setdefault(self, __key: Key, __default: Value = None) -> None:
def setdefault(self, __key, __default: Value = None) -> None:
__key = self._modify_key(__key)
__default = self._modify_value(__default)
dict.setdefault(self, __key, __default)
Expand All @@ -289,9 +306,9 @@ def pop(self, __key, default=NO_DEFAULT) -> Value:
__key = self._modify_key(__key)

if default is NO_DEFAULT:
value: Value = dict.pop(self, __key)
value = dict.pop(self, __key)
else:
value: Value = dict.pop(self, __key, default)
value = dict.pop(self, __key, default)

return value

Expand All @@ -309,11 +326,15 @@ def get(self, __key: Key, default=None):
return value

@overload
def update(self, __m: Mapping[Key, Value], **kwargs: Value) -> None:
def update(
self, other: SupportsKeysAndGetItem[Any, Value], /, **kwargs: Value
) -> None:
...

@overload
def update(self, __m: Iterable[Tuple[str, Any]], **kwargs: Value) -> None:
def update(
self, other: Iterable[Tuple[Any, Any]], /, **kwargs: Value
) -> None:
...

@overload
Expand All @@ -322,14 +343,14 @@ def update(self, **kwargs: Value) -> None:

def update(
self,
__m=None,
other=None,
**kwargs,
):
# If there is a ValueError have the inherited class deal with it.
with contextlib.suppress(ValueError):
if __m:
__m = self._iterable_to_modified_dict(__m)
if other:
other = self._iterable_to_modified_dict(other)
if kwargs:
kwargs = self._iterable_to_modified_dict(kwargs)

dict.update(self, __m or dict(), **kwargs)
dict.update(self, other or {}, **kwargs)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
long_description=README,
long_description_content_type='text/markdown',
keywords='python dict attribute dictionary attrdict mapping '
'key-mangling value-mangling',
'key-mangling value-mangling',
url='https://github.com/tybruno/modifiable-items-dictionary',
license='MIT',
package_data={'modifiable-items-dictionary': ['py.typed']},
Expand Down

0 comments on commit 2020ca7

Please sign in to comment.