Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement callable positional argument #4
- Loading branch information
1 parent
1e14e6f
commit 60b349b
Showing
4 changed files
with
143 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from _primitives.exceptions import PrimitiveError | ||
|
||
|
||
class Argument: | ||
"""An object appropriate to fake function arguments.""" | ||
|
||
def __init__(self, value): | ||
self.value = value | ||
|
||
def check(self, arg): | ||
"""Check argument match.""" | ||
if arg != self.value: | ||
raise PrimitiveError( | ||
f"Called with argument {arg!r} while expected {self.value!r}" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,67 @@ | ||
from _primitives.argument import Argument | ||
from _primitives.exceptions import PrimitiveError | ||
|
||
|
||
class Callable: | ||
"""An object appropriate to fake functions and methods.""" | ||
|
||
def __init__(self, *args): | ||
if args: | ||
self.return_value = args[0] | ||
else: | ||
self.return_value = None | ||
arguments, values = _arguments(args) | ||
self.check = _Check(arguments) | ||
self.return_value = _return_value(values) | ||
|
||
def __call__(self): | ||
def __call__(self, *args, **kwargs): | ||
"""Return predefined value.""" | ||
self.check(args, kwargs) | ||
return self.return_value | ||
|
||
|
||
def _arguments(args): | ||
arguments = [] | ||
values = [] | ||
for arg in args: | ||
if isinstance(arg, Argument): | ||
arguments.append(arg) | ||
else: | ||
values.append(arg) | ||
return arguments, values | ||
|
||
|
||
def _return_value(args): | ||
if len(args) > 1: | ||
raise PrimitiveError("'Callable' object should have only one return value") | ||
elif args: | ||
return args[0] | ||
|
||
|
||
class _Check: | ||
def __init__(self, arguments): | ||
self.arguments = arguments | ||
|
||
def __call__(self, args, kwargs): | ||
if kwargs: | ||
raise PrimitiveError("Positional arguments can not be called as keyword") | ||
iterator = _Iterator(args) | ||
for argument in self.arguments: | ||
value = iterator.get() | ||
argument.check(value) | ||
iterator.last() | ||
|
||
|
||
class _Iterator: | ||
def __init__(self, args): | ||
self.state = iter(args) | ||
|
||
def get(self): | ||
try: | ||
return next(self.state) | ||
except StopIteration: | ||
raise PrimitiveError("Called with less arguments than expected") | ||
|
||
def last(self): | ||
try: | ||
next(self.state) | ||
except StopIteration: | ||
pass | ||
else: | ||
raise PrimitiveError("Called with more arguments than expected") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
"""Fake objects designed with OOP in mind.""" | ||
from _primitives.argument import Argument | ||
from _primitives.callable import Callable | ||
|
||
|
||
__all__ = ["Callable"] | ||
__all__ = ["Argument", "Callable"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters