Skip to content

Commit 57440e0

Browse files
authored
Typing refactor (#23)
* Updating version * adding `pylint` and `mypy` * added py.typed * fixing mypy and pylint errors. * adding pylint and mypy to pipeline * add blue check. * fixing typing. * fixing typing. * adding badge for pylint and mypy
1 parent 71041d6 commit 57440e0

File tree

8 files changed

+58
-37
lines changed

8 files changed

+58
-37
lines changed

.github/workflows/lint-workflow.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,19 @@ jobs:
1717
- name: Install dependencies
1818
run: |
1919
python -m pip install --upgrade pip
20+
pip install blue
21+
pip install pylint
2022
pip install pylama
23+
pip install mypy
24+
- name: Check blue
25+
run: |
26+
blue . --check
27+
- name: Analysing the code with pylama
28+
run: |
29+
pylama --skip='tests/*'
2130
- name: Analysing the code with pylint
2231
run: |
23-
pylama --skip='tests/*'
32+
pylint modifiable_items_dictionary/
33+
- name: Analysing the code with mypy
34+
run: |
35+
mypy modifiable_items_dictionary/

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
[![Code Style: Blue](https://img.shields.io/badge/code%20style-blue-0000ff.svg)](https://github.com/psf/blue)
33
[![License: MIT](https://img.shields.io/badge/License-MIT-blueviolet.svg)](https://opensource.org/licenses/MIT)
44
[![codecov](https://codecov.io/gh/tybruno/modifiable-items-dictionary/branch/main/graph/badge.svg?token=ZO94EJFI3G)](https://codecov.io/gh/tybruno/modifiable-items-dictionary)
5-
5+
[![Pylint](https://img.shields.io/badge/Pylint-10.0%2F10-green)](10.0/10)
6+
[![Mypy](https://img.shields.io/badge/Mypy-checked-blue)](10.0/10)
67
# modifiable-items-dict
78

89
A simple, fast, typed, and tested implementation for a python3.6+ Modifiable Items dictionary. `ModifiableItemsDict`

modifiable_items_dictionary/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
"""modifiable_items_dictionary package
2+
3+
Subpackages:
4+
- modifiable_items_dictionary: Contains the ModifiableItemsDict and
5+
ModifiableItemsAttrDict classes.
6+
- modifiable_items_attribute_dictionary: Contains the ModifiableItemsAttrDict
7+
class.
8+
"""
19
from modifiable_items_dictionary.modifiable_items_dictionary import (
210
ModifiableItemsDict,
311
)

modifiable_items_dictionary/modifiable_items_attribute_dictionary.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@
1313
This module was heavily inspired by Raymond Hettinger's class.
1414
[1] Hettinger, R. (2023). (Advanced) Python For Engineers: Part 3.
1515
"""
16+
from typing import Any
17+
1618
from modifiable_items_dictionary.modifiable_items_dictionary import (
1719
ModifiableItemsDict,
1820
)
19-
from typing import Any
2021

2122

2223
class ModifiableItemsAttrDict(ModifiableItemsDict):
@@ -28,6 +29,7 @@ class ModifiableItemsAttrDict(ModifiableItemsDict):
2829
items. This means that in addition to the standard dictionary access
2930
syntax (dict["key"]), you can also use attribute syntax (dict.key).
3031
"""
32+
3133
__slots__ = ()
3234

3335
def __getattr__(self, name: str) -> Any:
@@ -50,11 +52,11 @@ def __getattr__(self, name: str) -> Any:
5052
"""
5153
try:
5254
value = self[name]
53-
except KeyError:
55+
except KeyError as error:
5456
raise AttributeError(
5557
f"'{self.__class__.__name__}' object has no attribute "
5658
f"'{name}'."
57-
)
59+
) from error
5860
return value
5961

6062
def __setattr__(self, name: str, value: Any) -> None:

modifiable_items_dictionary/modifiable_items_dictionary.py

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
[1] Hettinger, R. (2023). (Advanced) Python For Engineers: Part 3.
1111
"""
1212
import contextlib
13-
import multiprocessing.pool
13+
14+
# pylint: disable=no-name-in-module
1415
from typing import (
1516
Any,
1617
Callable,
@@ -25,6 +26,7 @@
2526
overload,
2627
)
2728

29+
2830
# Sentinel
2931
NO_DEFAULT = object()
3032

@@ -33,12 +35,12 @@
3335
Self = TypeVar('Self', bound='ModifiableItemsDict')
3436

3537
Key = Hashable
38+
_KT = TypeVar('_KT')
39+
_VT_co = TypeVar('_VT_co', covariant=True)
3640
Value = Any
3741
MappingCallable = Union[
3842
map,
39-
multiprocessing.pool.ThreadPool.map,
40-
multiprocessing.pool.ThreadPool.imap,
41-
multiprocessing.pool.ThreadPool.imap_unordered,
43+
Callable,
4244
]
4345
KeyCallable = Callable[[Any], Key]
4446
ValueCallable = Callable[[Any], Value]
@@ -75,7 +77,6 @@ class ModifiableItemsDict(dict):
7577

7678
__slots__ = ()
7779

78-
# TODO: Add validators
7980
_key_modifiers: KeyModifiers = None
8081
_value_modifiers: ValueModifiers = None
8182
_map_function: MappingCallable = map
@@ -189,12 +190,9 @@ def _create_modified_mapping(self, iterable):
189190
Dictionary with the modified keys and values.
190191
"""
191192

192-
new_mapping: Mapping[Key, Value] = {
193-
key: value
194-
for key, value in self._map_function(
195-
self._modify_key_and_item, iterable
196-
)
197-
}
193+
new_mapping = dict(
194+
self._map_function(self._modify_key_and_item, iterable)
195+
)
198196

199197
return new_mapping
200198

@@ -223,7 +221,17 @@ def fromkeys(
223221
cls,
224222
__iterable: Iterable[Key],
225223
__value: Optional[Union[Value, None]] = None,
226-
) -> Self:
224+
):
225+
"""Create a new dictionary with keys from iterable and values set to
226+
value.
227+
228+
Args:
229+
__iterable: Iterable of keys.
230+
__value: Value to set for each key. Default is None.
231+
232+
Returns:
233+
New dictionary with keys from iterable and values set to value.
234+
"""
227235
return cls(dict.fromkeys(__iterable, __value))
228236

229237
@overload
@@ -252,7 +260,7 @@ def __init__(
252260
if kwargs:
253261
kwargs = self._iterable_to_modified_dict(kwargs)
254262

255-
dict.__init__(self, iterable or dict(), **kwargs)
263+
dict.__init__(self, iterable or {}, **kwargs)
256264

257265
def __getitem__(self, k: Key) -> Any:
258266
k = self._modify_key(k)
@@ -272,7 +280,7 @@ def __contains__(self, __item: Value) -> bool:
272280
_is_in: bool = dict.__contains__(self, __item)
273281
return _is_in
274282

275-
def setdefault(self, __key: Key, __default: Value = None) -> None:
283+
def setdefault(self, __key, __default: Value = None) -> None:
276284
__key = self._modify_key(__key)
277285
__default = self._modify_value(__default)
278286
dict.setdefault(self, __key, __default)
@@ -289,9 +297,9 @@ def pop(self, __key, default=NO_DEFAULT) -> Value:
289297
__key = self._modify_key(__key)
290298

291299
if default is NO_DEFAULT:
292-
value: Value = dict.pop(self, __key)
300+
value = dict.pop(self, __key)
293301
else:
294-
value: Value = dict.pop(self, __key, default)
302+
value = dict.pop(self, __key, default)
295303

296304
return value
297305

@@ -308,18 +316,6 @@ def get(self, __key: Key, default=None):
308316
value: Union[Value, None] = dict.get(self, __key, default)
309317
return value
310318

311-
@overload
312-
def update(self, __m: Mapping[Key, Value], **kwargs: Value) -> None:
313-
...
314-
315-
@overload
316-
def update(self, __m: Iterable[Tuple[str, Any]], **kwargs: Value) -> None:
317-
...
318-
319-
@overload
320-
def update(self, **kwargs: Value) -> None:
321-
...
322-
323319
def update(
324320
self,
325321
__m=None,
@@ -332,4 +328,4 @@ def update(
332328
if kwargs:
333329
kwargs = self._iterable_to_modified_dict(kwargs)
334330

335-
dict.update(self, __m or dict(), **kwargs)
331+
dict.update(self, __m or {}, **kwargs)

modifiable_items_dictionary/py.typed

Whitespace-only changes.

requirements-test.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
# Test Requirements
22
pytest
33
pytest-cov
4-
blue
4+
blue
5+
mypy
6+
pylint

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Setup.py"""
22
import setuptools
33

4-
__version__ = 'v3.0.1'
4+
__version__ = 'v3.0.2'
55
__author__ = 'Tyler Bruno'
66
_description = (
77
'Typed and Tested Modifiable Items Dict and ModifiableItemsAttrDict which '
@@ -21,7 +21,7 @@
2121
long_description=README,
2222
long_description_content_type='text/markdown',
2323
keywords='python dict attribute dictionary attrdict mapping '
24-
'key-mangling value-mangling',
24+
'key-mangling value-mangling',
2525
url='https://github.com/tybruno/modifiable-items-dictionary',
2626
license='MIT',
2727
package_data={'modifiable-items-dictionary': ['py.typed']},

0 commit comments

Comments
 (0)