From 02a621dde7b1c0709504abb4adbe99d5e81c18b6 Mon Sep 17 00:00:00 2001 From: bleudev <95937737+bleudev@users.noreply.github.com> Date: Mon, 1 Jul 2024 23:29:07 +0300 Subject: [PATCH] Move `UStack` to `ustl` (#41) * UStack -> Stack -> (to) ustl. Edit setup.py and simplify working with packages. Add deprecation for UStack * fix issues from sourcery's review * Update examples/ustack.md Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * Update examples/ustack.md Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * Update examples/ustack.md Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> * Update examples/ustack.md Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> --------- Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> --- examples/ustack.md | 33 ++++++++-------- setup.py | 15 +++----- tests/test_ustack.py | 62 +++++++++++++++---------------- ufpy/__init__.py | 27 +++++++++++++- ufpy/ustl/__init__.py | 1 + ufpy/{ustack.py => ustl/stack.py} | 48 ++++++++++++------------ 6 files changed, 103 insertions(+), 83 deletions(-) create mode 100644 ufpy/ustl/__init__.py rename ufpy/{ustack.py => ustl/stack.py} (70%) diff --git a/examples/ustack.md b/examples/ustack.md index d38e279..4d9ee0c 100644 --- a/examples/ustack.md +++ b/examples/ustack.md @@ -1,21 +1,22 @@ -# UStack +# Stack ## Introduction -UStack is list with possibility to get only top element with useful features. [Wiki](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)) +A Stack is a list that allows access only to the top element and includes several useful features. [Wiki](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)) + +Firstly, import `Stack` from `ufpy` -Firstly, import `UStack` from `ufpy` ```python -from ufpy import UStack +from ufpy import Stack ``` -## Create UStack +## Create Stack -For creating UStack you should use this code: +To create a Stack, use the following code: ```python -s = UStack() # blank stack -s = UStack(1, 9, 2) # You can also provide elements as arguments -s = UStack(iterable=[9, 2, 8]) # Or with `iterable` kwarg +s = Stack() # blank stack +s = Stack(1, 9, 2) # You can also provide elements as arguments +s = Stack(iterable=[9, 2, 8]) # Or with `iterable` kwarg ``` ## Get / edit / delete top element @@ -102,13 +103,13 @@ len(s) You can check that stack is empty using `is_empty()` method: ```python -s = UStack() +s = Stack() s.is_empty() # True ``` -Also, you can use `if UStack` syntax for checking that stack is not empty +You can also use the `if Stack` syntax to check whether the stack is not empty ```python -s = UStack() +s = Stack() if s: print("Stack isn't empty!") else: @@ -120,18 +121,18 @@ else: You can use `repr()` with stacks. Because of it, you can print stacks: ```python -s = UStack(1, 9, 2) +s = Stack(1, 9, 2) print(s) # s[1, 9, 2] ``` -## Copying of UStack +## Copying of Stack -You can use `copy()` method for copying `UStack`s: +You can use `copy()` method for copying `Stack`s: ```python s.copy() ``` -You can also use `copy.copy()` function for copying `UStack`s: +You can use the `copy.copy()` function to copy `Stack`s: ```python from copy import copy diff --git a/setup.py b/setup.py index a8db12c..a3a0b35 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -from setuptools import setup +from setuptools import setup, find_packages from ufpy import __version__ @@ -9,13 +9,12 @@ 'requests>=2.31.0', ] +author = 'bleudev' +author_email = 'aitiiigg1@gmail.com' organization_name = 'honey-team' -author, author_email = 'bleudev', 'aitiiigg1@gmail.com' project_name = 'ufpy' github_url = f'https://github.com/{organization_name}/{project_name}' -def __package(name: str) -> str: - return f'{project_name}.{name}' setup( name=project_name, @@ -27,11 +26,7 @@ def __package(name: str) -> str: long_description=long_description, long_description_content_type='text/markdown', url=github_url, - packages=[ - project_name, - __package('typ'), - __package('github'), - ], + packages=find_packages(), classifiers=[ 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.12', @@ -39,4 +34,4 @@ def __package(name: str) -> str: zip_safe=False, python_requires=">=3.12", install_requires=install_requires -) \ No newline at end of file +) diff --git a/tests/test_ustack.py b/tests/test_ustack.py index 93d7d9d..8906712 100644 --- a/tests/test_ustack.py +++ b/tests/test_ustack.py @@ -1,66 +1,66 @@ import unittest from copy import copy -from ufpy import UStack +from ufpy import Stack class UStackTestCase(unittest.TestCase): def test_init(self): - s = UStack(1, 1, 2, 3, 5, 8) - s2 = UStack(*s.elements) - s3 = UStack(iterable=s2.elements) + s = Stack(1, 1, 2, 3, 5, 8) + s2 = Stack(*s.elements) + s3 = Stack(iterable=s2.elements) self.assertEqual(s, s2) self.assertEqual(s, s3) self.assertEqual(s2, s3) def test_elements(self): - s = UStack(1, 1, 2, 3, 5, 8) + s = Stack(1, 1, 2, 3, 5, 8) self.assertEqual(s.elements, [1, 1, 2, 3, 5, 8]) s.elements = 1, 2 - self.assertEqual(s, UStack(1, 2)) + self.assertEqual(s, Stack(1, 2)) del s.elements - self.assertEqual(s, UStack()) + self.assertEqual(s, Stack()) def test_top(self): - s = UStack(1, 1, 2, 3, 5, 8) + s = Stack(1, 1, 2, 3, 5, 8) self.assertEqual(s.top, 8) s.top = 10 - self.assertEqual(s, UStack(1, 1, 2, 3, 5, 10)) + self.assertEqual(s, Stack(1, 1, 2, 3, 5, 10)) del s.top - self.assertEqual(s, UStack(1, 1, 2, 3, 5)) + self.assertEqual(s, Stack(1, 1, 2, 3, 5)) def test_pop(self): - s = UStack(1, 1, 2, 3, 5, 8) + s = Stack(1, 1, 2, 3, 5, 8) self.assertEqual(s.pop(), 8) - self.assertEqual(s, UStack(1, 1, 2, 3, 5)) + self.assertEqual(s, Stack(1, 1, 2, 3, 5)) def test_push(self): - s = UStack(1, 1, 2, 3, 5, 8) - self.assertEqual(s.push(2, 1), UStack(1, 1, 2, 3, 5, 8, 2, 1)) - self.assertEqual(s, UStack(1, 1, 2, 3, 5, 8, 2, 1)) + s = Stack(1, 1, 2, 3, 5, 8) + self.assertEqual(s.push(2, 1), Stack(1, 1, 2, 3, 5, 8, 2, 1)) + self.assertEqual(s, Stack(1, 1, 2, 3, 5, 8, 2, 1)) def test_remove(self): - s = UStack(1, 1, 2, 3, 5, 8) - self.assertEqual(s.remove(1), UStack(1, 2, 3, 5, 8)) - self.assertEqual(s, UStack(1, 2, 3, 5, 8)) + s = Stack(1, 1, 2, 3, 5, 8) + self.assertEqual(s.remove(1), Stack(1, 2, 3, 5, 8)) + self.assertEqual(s, Stack(1, 2, 3, 5, 8)) def test_clear(self): - s = UStack(1, 1, 2, 3, 5, 8) - s2 = UStack(1, 1, 2, 3, 5, 8) + s = Stack(1, 1, 2, 3, 5, 8) + s2 = Stack(1, 1, 2, 3, 5, 8) del s2.elements - self.assertEqual(s.clear(), UStack()) + self.assertEqual(s.clear(), Stack()) self.assertEqual(s, s2) def test_copy(self): # with copy - s = UStack(1, 1, 2, 3, 5, 8) + s = Stack(1, 1, 2, 3, 5, 8) s2 = s.copy() s3 = copy(s2) @@ -79,28 +79,28 @@ def test_copy(self): self.assertEqual(id(s4), id(s5)) def test_call(self): - s = UStack(1, 1, 2, 3, 5, 8) + s = Stack(1, 1, 2, 3, 5, 8) def f(i, v): return v * i - self.assertEqual(s(f), UStack(0, 1, 4, 9, 20, 40)) + self.assertEqual(s(f), Stack(0, 1, 4, 9, 20, 40)) def test_math_operations(self): - s = UStack(1, 1, 2, 3, 5, 8) - self.assertEqual(s + 1, UStack(1, 1, 2, 3, 5, 8, 1)) - self.assertEqual(s - 1, UStack(1, 2, 3, 5, 8)) - self.assertEqual(s * 2, UStack(2, 2, 4, 6, 10, 16)) - self.assertEqual(s / 2, UStack(0.5, 0.5, 1, 1.5, 2.5, 4)) + s = Stack(1, 1, 2, 3, 5, 8) + self.assertEqual(s + 1, Stack(1, 1, 2, 3, 5, 8, 1)) + self.assertEqual(s - 1, Stack(1, 2, 3, 5, 8)) + self.assertEqual(s * 2, Stack(2, 2, 4, 6, 10, 16)) + self.assertEqual(s / 2, Stack(0.5, 0.5, 1, 1.5, 2.5, 4)) def test_len_and_empty(self): - s = UStack(1, 1, 2, 3, 5, 8) + s = Stack(1, 1, 2, 3, 5, 8) self.assertEqual(len(s), 6) self.assertFalse(s.is_empty()) self.assertTrue(bool(s)) def test_repr(self): - s = UStack(1, 1, 2, 3, 5, 8) + s = Stack(1, 1, 2, 3, 5, 8) self.assertEqual(repr(s), 's[1, 1, 2, 3, 5, 8]') diff --git a/ufpy/__init__.py b/ufpy/__init__.py index 1af4da7..47cbb52 100644 --- a/ufpy/__init__.py +++ b/ufpy/__init__.py @@ -1,15 +1,38 @@ -__version__ = '0.1.2' +# Deprecated +def __deprecated(deprecated_name: str, x, start_version: str, end_version: str): + """This is a decorator which can be used to mark functions + as deprecated. It will result in a warning being emitted + when the function is used.""" + from functools import wraps + from warnings import warn, simplefilter + @wraps(x) + def new_func(*args, **kwargs): + simplefilter('always', DeprecationWarning) # turn off filter + warn(f"{deprecated_name} is deprecated in {start_version} and will be deleted in {end_version}. " + f"Use {x.__name__} instead.", + category=DeprecationWarning, + stacklevel=2) + simplefilter('default', DeprecationWarning) # reset filter + return x(*args, **kwargs) + return new_func + + +__version__ = '0.2-dev' from ufpy.cmp import * from ufpy.math_op import * from ufpy.udict import * -from ufpy.ustack import * from ufpy.utils import * # Typing package __typ_version__ = '0.1' from ufpy.typ import * +# Ustl package +__ustl_version = '0.1' +from ufpy.ustl import * +UStack = __deprecated("UStack", Stack, '0.2', '0.5') + # Path package __path_version__ = '0.1' from ufpy.path import * diff --git a/ufpy/ustl/__init__.py b/ufpy/ustl/__init__.py new file mode 100644 index 0000000..cf00bd9 --- /dev/null +++ b/ufpy/ustl/__init__.py @@ -0,0 +1 @@ +from ufpy.ustl.stack import * diff --git a/ufpy/ustack.py b/ufpy/ustl/stack.py similarity index 70% rename from ufpy/ustack.py rename to ufpy/ustl/stack.py index f8aad74..ec41188 100644 --- a/ufpy/ustack.py +++ b/ufpy/ustl/stack.py @@ -7,21 +7,21 @@ from ufpy.typ import AnyCollection, NumberLiteral, SupportsMul, SupportsTrueDiv, Empty __all__ = ( - "UStack", + "Stack", ) T = TypeVar("T") T2 = TypeVar("T2") -def convert_to_stack(other: UStack[T] | AnyCollection[T] | T) -> UStack[T]: - if isinstance(other, UStack): +def convert_to_stack(other: Stack[T] | AnyCollection[T] | T) -> Stack[T]: + if isinstance(other, Stack): return other if isinstance(other, (list, tuple)): - return UStack(iterable=other) - return UStack(other) + return Stack(iterable=other) + return Stack(other) -def convert_to_list_for_mul_and_div(other: UStack[T] | AnyCollection[T] | T, __len: int = None) -> list[T]: - if isinstance(other, UStack): +def convert_to_list_for_mul_and_div(other: Stack[T] | AnyCollection[T] | T, __len: int = None) -> list[T]: + if isinstance(other, Stack): return other.elements if isinstance(other, (list, tuple)): return list(other) @@ -30,7 +30,7 @@ def convert_to_list_for_mul_and_div(other: UStack[T] | AnyCollection[T] | T, __l @cmp_generator @i_generator @r_generator -class UStack(Generic[T]): +class Stack(Generic[T]): """ Class for simplifying working with stacks in Python. """ @@ -79,48 +79,48 @@ def pop(self) -> T: """ return self.__elements.pop() - def push(self, *items: T) -> UStack[T]: + def push(self, *items: T) -> Stack[T]: """Append items to stack""" self.__elements.extend(items) - return UStack(iterable=self.__elements) + return Stack(iterable=self.__elements) - def remove(self, *items: T) -> UStack[T]: + def remove(self, *items: T) -> Stack[T]: for i in items: self.__elements.remove(i) - return UStack(iterable=self.__elements) + return Stack(iterable=self.__elements) - def clear(self) -> Empty[UStack]: + def clear(self) -> Empty[Stack]: del self.elements return self # copying - def copy(self) -> UStack[T]: - return UStack(iterable=self.__elements.copy()) + def copy(self) -> Stack[T]: + return Stack(iterable=self.__elements.copy()) def __copy__(self): return self.copy() # call - def __call__(self, func: Callable[[int, T], T2]) -> UStack[T2]: + def __call__(self, func: Callable[[int, T], T2]) -> Stack[T2]: elements = self.__elements.copy() for i, v in enumerate(elements): elements[i] = func(i, v) - return UStack(iterable=elements) + return Stack(iterable=elements) # math operations - def __add__(self, other: UStack[T2] | AnyCollection[T2] | T2) -> UStack[T | T2]: + def __add__(self, other: Stack[T2] | AnyCollection[T2] | T2) -> Stack[T | T2]: other = convert_to_stack(other) result = self.copy() return result.push(*other.elements) - def __sub__(self, other: UStack[T] | AnyCollection[T] | T) -> UStack[T]: + def __sub__(self, other: Stack[T] | AnyCollection[T] | T) -> Stack[T]: other = convert_to_stack(other) result = self.copy() return result.remove(*other.elements) def __mul__( - self: UStack[SupportsMul], other: UStack[NumberLiteral] | AnyCollection[NumberLiteral] | NumberLiteral - ) -> UStack[SupportsMul]: + self: Stack[SupportsMul], other: Stack[NumberLiteral] | AnyCollection[NumberLiteral] | NumberLiteral + ) -> Stack[SupportsMul]: other = convert_to_list_for_mul_and_div(other, len(self)) def mul(i: int, v: SupportsMul) -> SupportsMul: @@ -129,8 +129,8 @@ def mul(i: int, v: SupportsMul) -> SupportsMul: return self(mul) def __truediv__( - self: UStack[SupportsTrueDiv], other: UStack[NumberLiteral] | AnyCollection[NumberLiteral] | NumberLiteral - ) -> UStack[SupportsTrueDiv]: + self: Stack[SupportsTrueDiv], other: Stack[NumberLiteral] | AnyCollection[NumberLiteral] | NumberLiteral + ) -> Stack[SupportsTrueDiv]: other = convert_to_list_for_mul_and_div(other, len(self)) def div(i: int, v: SupportsTrueDiv) -> SupportsTrueDiv: @@ -148,7 +148,7 @@ def is_empty(self) -> bool: def __bool__(self) -> bool: return not self.is_empty() - def __eq__(self, other: UStack[T2]) -> bool: + def __eq__(self, other: Stack[T2]) -> bool: return self.elements == other.elements # Transform to other types