diff --git a/.codeclimate.yml b/.codeclimate.yml index 09348219425cef40b9f5bfb35e5c96ae8f7c2673..f1423473ac907469c359173d8a94543d9797fce8 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -19,4 +19,4 @@ exclude_paths: - docs/** ratings: paths: - - satella/** \ No newline at end of file + - satella/** diff --git a/docs/coding/structures.rst b/docs/coding/structures.rst index 09183ad0107d8cd70395e956ddec434250b488ac..17807c9b21fe55c8eaee8c5f620ff0d3c51f1080 100644 --- a/docs/coding/structures.rst +++ b/docs/coding/structures.rst @@ -5,7 +5,7 @@ This essentially allows you to have a heap object that will pretty much behave like the `heapq <https://docs.python.org/2/library/heapq.html>` library. .. autoclass:: satella.coding.Heap - :members: +:members: TimeBasedHeap --------- @@ -14,4 +14,12 @@ Time-based heap is a good structure if you have many callbacks set to fire at a time in the future. It functions very like a normal Heap. .. autoclass:: satella.coding.TimeBasedHeap - :members: +:members: + +typednamedtuple +--------------- + +It's a named tuple, but it has typed fields. You will get a TypeError if you +try to assign something else there. + +.. autofunction:: satella.coding.typednamedtuple diff --git a/docs/conf.py b/docs/conf.py index 56645d9e374c21e4bb97d09460b140e46bf5eb5a..654fa5c0a55ced5256dab1fccfee268198e70daf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -60,6 +60,7 @@ author = u'Piotr MaĹlanka' # # The short X.Y version. from satella import __version__ + version = '.'.join(__version__.split('.', 2)[:2]) # The full version, including alpha/beta/rc tags. release = __version__ diff --git a/docs/index.rst b/docs/index.rst index 1b64a475fbdf69395cef432eff9f5a2ffa61bf17..58dfc828679c1c179cae4ab5c827aad2cc1ff3bd 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -2,17 +2,17 @@ Welcome to satella's documentation! =================================== .. toctree:: - :maxdepth: 2 - :caption: Contents: +:maxdepth: 2 + :caption: Contents: - coding/monitor - coding/debug - coding/typechecking - coding/structures - instrumentation/traceback - instrumentation/metrics - source/modules - posix + coding/monitor + coding/debug + coding/typechecking + coding/structures + instrumentation/traceback + instrumentation/metrics + source/modules + posix Indices and tables diff --git a/examples/echoist/__init__.py b/examples/echoist/__init__.py deleted file mode 100644 index d819f5f6c41dd2243caebf0ab98f7010811b0f96..0000000000000000000000000000000000000000 --- a/examples/echoist/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -# coding=UTF-8 -""" -Simple Echo service -""" -from __future__ import print_function, absolute_import, division -import six -import logging - -logger = logging.getLogger(__name__) - - diff --git a/examples/echoist/run.py b/examples/echoist/run.py deleted file mode 100644 index fd0fb6ffcc05e5c53d26253c164c9afc211270e4..0000000000000000000000000000000000000000 --- a/examples/echoist/run.py +++ /dev/null @@ -1,20 +0,0 @@ -# coding=UTF-8 -""" -It sounds like a melody -""" -from __future__ import print_function, absolute_import, division -import six -import logging -import socket - -logger = logging.getLogger(__name__) - -from satella.posix import daemonize - - -if __name__ == '__main__': - - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.bind(('0.0.0.0', 7)) - - daemonize(uid='daemon', gid='daemon') diff --git a/satella/coding/__init__.py b/satella/coding/__init__.py index 7c93216ec6a3f8be881d09f1acf6a125f18e5782..c4530c942622f7356cfe560cfe730453eed41795 100644 --- a/satella/coding/__init__.py +++ b/satella/coding/__init__.py @@ -8,24 +8,22 @@ from .algos import merge_dicts from .concurrent import Monitor, RMonitor, CallableGroup from .recast_exceptions import rethrow_as, silence_excs from .structures import TimeBasedHeap, Heap, typednamedtuple, OmniHashableMixin +from .structures import TimeBasedHeap, Heap, typednamedtuple, OmniHashableMixin, Singleton from .typecheck import typed, Callable, Sequence, \ TypeVar, Mapping, Iterable, Any, Optional, CallSignature, \ Number, coerce, Set, Dict, List, Tuple, checked_coerce, for_argument, \ precondition, PreconditionError -from .structures import TimeBasedHeap, Heap, typednamedtuple, OmniHashableMixin -from .singleton import Singleton - __all__ = [ 'typednamedtuple', 'OmniHashableMixin' - 'TimeBasedHeap', 'Heap', 'CallableGroup', + 'TimeBasedHeap', 'Heap', 'CallableGroup', 'Monitor', 'RMonitor', 'merge_dicts', 'typed', 'NewType', 'Callable', 'Sequence', 'coerce' - 'TypeVar','Mapping', 'Iterable', 'Union', 'Any', 'Optional', + 'TypeVar', 'Mapping', 'Iterable', 'Union', 'Any', + 'Optional', 'CallSignature', 'Number', 'Set', 'Dict', 'List', 'Tuple', 'checked_coerce', 'for_argument', 'precondition', 'PreconditionError', 'rethrow_as', 'silence_excs', 'Singleton' ] - diff --git a/satella/coding/structures/__init__.py b/satella/coding/structures/__init__.py index a1d678b141417c67b1660810e2ae1ad907ace905..077ee0d68a414797b0753a6eb10622952e9dede2 100644 --- a/satella/coding/structures/__init__.py +++ b/satella/coding/structures/__init__.py @@ -1,5 +1,14 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division +__all__ = [ + 'typednamedtuple', + 'Heap', + 'TimeBasedHeap', + 'OmniHashableMixin', + 'Singleton' +] + +from .singleton import Singleton from .structures import * from .typednamedtuple import * diff --git a/satella/coding/singleton.py b/satella/coding/structures/singleton.py similarity index 99% rename from satella/coding/singleton.py rename to satella/coding/structures/singleton.py index 063e0c5cfd512ad9f3bbd48fe0e4a0e25ff2f375..dd4de72a0bd5860bb7c85203b2e66b21be32d9c0 100644 --- a/satella/coding/singleton.py +++ b/satella/coding/structures/singleton.py @@ -67,5 +67,4 @@ else: """ return _SingletonWrapper(cls) - Singleton = singleton diff --git a/satella/coding/typecheck/argparse.py b/satella/coding/typecheck/argparse.py index 13622fac6af66c83d39d2ae9343a1d934f278370..836135891ba4b8c54c78bd71017477b0c3647915 100644 --- a/satella/coding/typecheck/argparse.py +++ b/satella/coding/typecheck/argparse.py @@ -1,10 +1,12 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division + import inspect -from copy import copy import itertools -from .basics import * from collections import namedtuple +from copy import copy + +from .basics import * __all__ = [ '_CSArgument', diff --git a/satella/coding/typecheck/basics.py b/satella/coding/typecheck/basics.py index 079275fde932091a818335120029eff58a1fa33c..5eeac9d7957e281996ab89ae904855da6ff9803a 100644 --- a/satella/coding/typecheck/basics.py +++ b/satella/coding/typecheck/basics.py @@ -1,7 +1,8 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division -import typing + import numbers +import typing __all__ = [ 'Callable', 'Sequence', 'Number', 'Mapping', 'Iterable', 'Any', @@ -9,7 +10,6 @@ __all__ = [ '_NotGiven', '_NoDefault', '_NOP', '_TRUE' ] - Callable = lambda *args: typing.Callable Sequence = typing.Sequence Number = numbers.Real @@ -23,6 +23,7 @@ Tuple = lambda *opt: tuple Dict = lambda *p: dict Set = lambda *p: set + # Internal tokens - only instances will be class _NotGiven(object): pass diff --git a/tests/test_coding/test_debug.py b/tests/test_coding/test_debug.py index 504638aeb05f1829462932db1c64a1b3106a846e..1e48a840ad61e8b782ca7cf9a3b0182a71e66503 100644 --- a/tests/test_coding/test_debug.py +++ b/tests/test_coding/test_debug.py @@ -11,9 +11,7 @@ from satella.coding import typed, CallSignature, Number, coerce, Optional, \ class TestTypecheck(unittest.TestCase): - def test_precondition(self): - @precondition('len(x) == 1', lambda x: x == 1, None) def return_double(x, y, z): pass @@ -21,7 +19,7 @@ class TestTypecheck(unittest.TestCase): self.assertRaises(PreconditionError, lambda: return_double([], 1, 5)) self.assertRaises(PreconditionError, lambda: return_double([1], 2, 5)) return_double([1], 1, 'dupa') - + def test_cls(self): # if we don't care about apps class Lol(object): @@ -39,7 +37,6 @@ class TestTypecheck(unittest.TestCase): Lol().lel([], {}, (), set([1]), lambda a: None) def test_che_co2(self): - @checked_coerce((int, None)) def p(a): return a @@ -65,7 +62,6 @@ class TestTypecheck(unittest.TestCase): self.assertIsInstance(testa('5'), int) def test_checked_coerce(self): - @checked_coerce([(str, int), int], returns=(int, float)) def testa(a): return a @@ -144,7 +140,7 @@ class TestTypecheck(unittest.TestCase): @typed(Optional(int)) def testa(a=5): pass - + self.assertRaises(TypeError, lambda: testa(2.0)) testa(a=2.0) self.assertRaises(TypeError, lambda: testa('yuyu')) @@ -152,7 +148,6 @@ class TestTypecheck(unittest.TestCase): testa(a=6) def test_shorter_coerces(self): - @coerce(int, None, str) def test(a, b, c, d, e): return a, b, c, d, e @@ -174,10 +169,9 @@ class TestTypecheck(unittest.TestCase): self.assertEqual(Wtf().add('1', '2.5'), 3.5) def test_coerce_result(self): - @coerce(returns=str) def add(a, b): - return a+b + return a + b self.assertEqual(add(1, 2), '3') @@ -189,8 +183,6 @@ class TestTypecheck(unittest.TestCase): Wtf().add(1, 2.5) - - def test_T2(self): @typed((int, None)) def testa(a=5): diff --git a/tests/test_coding/test_singleton.py b/tests/test_coding/test_singleton.py index 7b2d8c6866af504c4e2e77e51d5ecdb1637d8023..f57b80fd48a7f2f9240f472fd42022be6672e2bb 100644 --- a/tests/test_coding/test_singleton.py +++ b/tests/test_coding/test_singleton.py @@ -1,12 +1,13 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division + import unittest + from satella.coding import Singleton class TestSingleton(unittest.TestCase): def test_singleton(self): - @Singleton class MyClass(object): def __init__(self): @@ -18,4 +19,3 @@ class TestSingleton(unittest.TestCase): a.a = 6 self.assertEqual(b.a, 6) - diff --git a/tests/test_coding/test_structures.py b/tests/test_coding/test_structures.py index 0a6bb5a40099b317c070d95b33b11b65f1ca145e..0080ba55a0f119912eb653c568d5e92a8021dfba 100644 --- a/tests/test_coding/test_structures.py +++ b/tests/test_coding/test_structures.py @@ -1,13 +1,14 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division +import copy import unittest +import mock +import six + from satella.coding import TimeBasedHeap, Heap, CallableGroup, typednamedtuple, \ OmniHashableMixin -import six -import copy -import mock class TestCallableGroup(unittest.TestCase): @@ -16,9 +17,7 @@ class TestCallableGroup(unittest.TestCase): class TestTimeBasedHeap(unittest.TestCase): - def test_omni(self): - class Omni(OmniHashableMixin): _HASH_FIELDS_TO_USE = ['a'] diff --git a/tests/test_posix/__init__.py b/tests/test_posix/__init__.py index 3d4da939ae36abfaaf9f0c48617e873f1a1d2e8a..6864cbaa7357da2b13bec13e6c643718243eeb51 100644 --- a/tests/test_posix/__init__.py +++ b/tests/test_posix/__init__.py @@ -27,8 +27,10 @@ class TestPidlock(unittest.TestCase): class TestDaemon(unittest.TestCase): @unittest.skipIf('win' in sys.platform, 'Running on Windows') def test_daemonize(self): - with patch('sys.stdin') as stdin, patch('sys.stdout') as stdout, patch('sys.stderr') as stderr, \ - patch('os.fork', return_value=0) as fork, patch('os.umask') as umask, patch('os.setsid') as setsid, \ + with patch('sys.stdin') as stdin, patch('sys.stdout') as stdout, patch( + 'sys.stderr') as stderr, \ + patch('os.fork', return_value=0) as fork, patch('os.umask') as umask, patch( + 'os.setsid') as setsid, \ patch('os.chdir') as chdir, patch('sys.exit', new=lambda: 0) as exit: from satella.posix import daemonize diff --git a/tests/test_posix/test_suicide.py b/tests/test_posix/test_suicide.py index cdf042901cb5545913db2e4bd0711e4f8bd5f787..8cf321c3ce41418a67d5abbacc9df3135b141838 100644 --- a/tests/test_posix/test_suicide.py +++ b/tests/test_posix/test_suicide.py @@ -1,12 +1,13 @@ # coding=UTF-8 from __future__ import print_function, absolute_import, division + import os import unittest + from satella.posix import suicide class TestSuicide(unittest.TestCase): - def test_suicide(self): pcid = os.fork()