-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from cbefus/abc
Rework to use an abstract base class.
- Loading branch information
Showing
7 changed files
with
138 additions
and
134 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
This file was deleted.
Oops, something went wrong.
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 @@ | ||
from .optional import * |
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,12 @@ | ||
"""compatible_abc | ||
This module exports a single class, CompatibleABC. | ||
It is necessary to provide the same behavior in | ||
Python 2 and Python 3. | ||
The implementation was taken from https://stackoverflow.com/a/38668373 | ||
""" | ||
from abc import ABCMeta | ||
|
||
|
||
CompatibleABC = ABCMeta('ABC', (object,), {'__slots__': ()}) |
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,109 @@ | ||
from abc import abstractmethod | ||
|
||
from .compatible_abc import CompatibleABC | ||
|
||
|
||
class Optional(object): | ||
@staticmethod | ||
def of(thing): | ||
return _Nothing() if thing is None else _Something(thing) | ||
|
||
@staticmethod | ||
def empty(): | ||
return _Nothing() | ||
|
||
|
||
class _AbstractOptional(CompatibleABC): | ||
|
||
@abstractmethod | ||
def is_present(self): | ||
pass | ||
|
||
def is_empty(self): | ||
return not self.is_present() | ||
|
||
@abstractmethod | ||
def get(self): | ||
pass | ||
|
||
@abstractmethod | ||
def if_present(self, consumer): | ||
pass | ||
|
||
@abstractmethod | ||
def or_else(self, procedure): | ||
pass | ||
|
||
@abstractmethod | ||
def map(self, func): | ||
pass | ||
|
||
@abstractmethod | ||
def flat_map(self, func): | ||
pass | ||
|
||
|
||
class _Nothing(_AbstractOptional): | ||
def is_present(self): | ||
return False | ||
|
||
def get(self): | ||
raise OptionalAccessOfEmptyException( | ||
"You cannot call get on an empty optional" | ||
) | ||
|
||
def if_present(self, consumer): | ||
return self | ||
|
||
def or_else(self, procedure): | ||
return procedure() | ||
|
||
def map(self, func): | ||
return self | ||
|
||
def flat_map(self, func): | ||
return self | ||
|
||
def __eq__(self, other): | ||
return isinstance(other, _Nothing) | ||
|
||
|
||
class _Something(_AbstractOptional): | ||
def __init__(self, value): | ||
self.__value = value | ||
|
||
def is_present(self): | ||
return True | ||
|
||
def get(self): | ||
return self.__value | ||
|
||
def if_present(self, consumer): | ||
consumer(self.get()) | ||
return self | ||
|
||
def or_else(self, procedure): | ||
return self | ||
|
||
def map(self, func): | ||
return Optional.of(func(self.get())) | ||
|
||
def flat_map(self, func): | ||
res = func(self.get()) | ||
if not isinstance(res, _AbstractOptional): | ||
raise FlatMapFunctionDoesNotReturnOptionalException( | ||
"Mapping function to flat_map must return Optional." | ||
) | ||
|
||
return res | ||
|
||
def __eq__(self, other): | ||
return isinstance(other, _Something) and self.get() == other.get() | ||
|
||
|
||
class OptionalAccessOfEmptyException(Exception): | ||
pass | ||
|
||
|
||
class FlatMapFunctionDoesNotReturnOptionalException(Exception): | ||
pass |
Empty file.
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