Skip to content

Commit

Permalink
Add python stub
Browse files Browse the repository at this point in the history
  • Loading branch information
RF-Tar-Railt committed May 27, 2023
1 parent ec701a3 commit bb27fbd
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 6 deletions.
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
include LICENSE README.rst MANIFEST MANIFEST.in
graft src
global-exclude *.pyc
global-exclude *.cache
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from setuptools import setup, Extension

extensions = [
Extension("lru", ["src/lru.c"]),
Extension("lru._lru", ["src/lru/_lru.c"]),
]

args = {
Expand Down
3 changes: 3 additions & 0 deletions src/lru/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from ._lru import LRU as LRU # noqa: F401

__all__ = ["LRU"]
63 changes: 63 additions & 0 deletions src/lru/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from typing import (
Any,
Callable,
Generic,
Hashable,
Iterable,
TypeVar,
overload,
Protocol
)

_KT = TypeVar("_KT", bound=Hashable)
_VT = TypeVar("_VT")
_VT_co = TypeVar("_VT_co", covariant=True)
_T = TypeVar("_T")


class __SupportsKeysAndGetItem(Protocol[_KT, _VT_co]):
def keys(self) -> Iterable[_KT]: ...
def __getitem__(self, __key: _KT) -> _VT_co: ...


class LRU(Generic[_KT, _VT]):
@overload
def __init__(self, size: int) -> None: ...
@overload
def __init__(self, size: int, callback: Callable[[_KT, _VT], Any]) -> None: ...
def clear(self) -> None: ...
@overload
def get(self, key: _KT) -> _VT | None: ...
@overload
def get(self, key: _KT, instead: _VT | _T) -> _VT | _T: ...
def get_size(self) -> int: ...
def has_key(self, key: _KT) -> bool: ...
def keys(self) -> list[_KT]: ...
def values(self) -> list[_VT]: ...
def items(self) -> list[tuple[_KT, _VT]]: ...
def peek_first_item(self) -> tuple[_KT, _VT] | None: ...
def peek_last_item(self) -> tuple[_KT, _VT] | None: ...
@overload
def pop(self, key: _KT) -> _VT | None: ...
@overload
def pop(self, key: _KT, default: _VT | _T) -> _VT | _T: ...
def popitem(self, least_recent: bool = ...) -> tuple[_KT, _VT]: ...
@overload
def setdefault(self: LRU[_KT, _T | None], key: _KT) -> _T | None: ...
@overload
def setdefault(self, key: _KT, default: _VT) -> _VT: ...
def set_callback(self, callback: Callable[[_KT, _VT], Any] | None) -> None: ...
def set_size(self, size: int) -> None: ...
@overload
def update(self, __m: __SupportsKeysAndGetItem[_KT, _VT], **kwargs: _VT) -> None: ...
@overload
def update(self, __m: Iterable[tuple[_KT, _VT]], **kwargs: _VT) -> None: ...
@overload
def update(self, **kwargs: _VT) -> None: ...
def get_stats(self) -> tuple[int, int]: ...
def __contains__(self, __o: Any) -> bool: ...
def __delitem__(self, key: _KT) -> None: ...
def __getitem__(self, item: _KT) -> _VT: ...
def __len__(self) -> int: ...
def __repr__(self) -> str: ...
def __setitem__(self, key: _KT, value: _VT) -> None: ...
4 changes: 2 additions & 2 deletions src/lru.c → src/lru/_lru.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ node_repr(Node* self)

static PyTypeObject NodeType = {
PyVarObject_HEAD_INIT(NULL, 0)
"lru.Node", /* tp_name */
"_lru.Node", /* tp_name */
sizeof(Node), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)node_dealloc,/* tp_dealloc */
Expand Down Expand Up @@ -711,7 +711,7 @@ PyDoc_STRVAR(lru_doc,

static PyTypeObject LRUType = {
PyVarObject_HEAD_INIT(NULL, 0)
"lru.LRU", /* tp_name */
"_lru.LRU", /* tp_name */
sizeof(LRU), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)LRU_dealloc, /* tp_dealloc */
Expand Down
6 changes: 3 additions & 3 deletions test/test_lru.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,11 @@ def test_pop(self):
self.assertEqual(0, len(l))
with self.assertRaises(KeyError) as ke:
l.pop(4)
self.assertEqual(4, ke.args[0])
self.assertEqual(4, ke.args[0]) # type: ignore
self.assertEqual((2, 2), l.get_stats())
self.assertEqual(0, len(l))
with self.assertRaises(TypeError):
l.pop()
l.pop() # type: ignore

def test_popitem(self):
l = LRU(3)
Expand All @@ -265,7 +265,7 @@ def test_popitem(self):
self.assertEqual((2, '2'), l.popitem(True))
with self.assertRaises(KeyError) as ke:
l.popitem()
self.assertEqual('popitem(): LRU dict is empty', ke.args[0])
self.assertEqual('popitem(): LRU dict is empty', ke.args[0]) # type: ignore
self.assertEqual((0, 0), l.get_stats())

def test_stats(self):
Expand Down

0 comments on commit bb27fbd

Please sign in to comment.