requiresthat 2025.6.17.0__tar.gz → 2025.6.18.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: requiresthat
3
- Version: 2025.6.17.0
3
+ Version: 2025.6.18.1
4
4
  Summary: Support for requirements-assisted development
5
5
  Author-email: Ann T Ropea <bedhanger@gmx.de>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "requiresthat"
7
- version = "2025.6.17.0"
7
+ version = "2025.6.18.1"
8
8
  authors = [
9
9
  {name = "Ann T Ropea", email = "bedhanger@gmx.de"},
10
10
  ]
@@ -0,0 +1,8 @@
1
+ from ._requires import (
2
+ requires,
3
+ RequirementNotFulfilledError,
4
+ NoCallableConstructError,
5
+ APRIORI,
6
+ POSTMORTEM,
7
+ BEFOREANDAFTER,
8
+ )
@@ -0,0 +1,34 @@
1
+ import textwrap
2
+
3
+ class RequirementNotFulfilledError(Exception):
4
+ """Raise this when a requirement is found wanting"""
5
+
6
+ def __init__(self, that, when, subwhen=str(), msg=None):
7
+ """Show a default or a user-provided message indicating that some condition is unmet"""
8
+
9
+ if subwhen:
10
+ subwhen = f' ({subwhen.name!r})'
11
+ self.default_msg = textwrap.dedent(f"""
12
+ {that!r} ({when.name!r}{subwhen}) does not hold
13
+ """).strip()
14
+
15
+ # Call the base class' constructor to init the exception class
16
+ super().__init__(msg or self.default_msg)
17
+
18
+ class NoCallableConstructError(Exception):
19
+ """Raise this when a construct is not callable"""
20
+
21
+ def __init__(self, construct, msg=None):
22
+ """Show a default or a user-provided message"""
23
+
24
+ self.default_msg = textwrap.dedent(f"""
25
+ {construct!r} does not seem to be callable
26
+
27
+ You have managed to place the decorator before a construct that is not callable
28
+ *without* tripping the Python interpreter. Maybe you are a wizard?
29
+
30
+ But, no, we can't carry on like that. Sorry!
31
+ """).strip()
32
+
33
+ # Call the base class' constructor to init the exception class
34
+ super().__init__(msg or self.default_msg)
@@ -0,0 +1,61 @@
1
+ """See the README file"""
2
+
3
+ from typing import Optional, Callable
4
+ from functools import wraps
5
+
6
+ from ._when import When, APRIORI, POSTMORTEM, BEFOREANDAFTER
7
+ from ._exceptions import RequirementNotFulfilledError, NoCallableConstructError
8
+
9
+ def requires(that, when: When = APRIORI) -> Optional[Callable]:
10
+ """Require <that> of the decoratee, and require it <when>"""
11
+
12
+ def func_wrapper(func: Callable) -> Optional[Callable]:
13
+ """First-level wrap the decoratee"""
14
+
15
+ @wraps(func)
16
+ def inner_wrapper(self, *pargs, **kwargs) -> Optional[Callable]:
17
+ """Wrap the first-level wrapper
18
+
19
+ The wrapping stops here...
20
+ """
21
+ try:
22
+ assert callable(func)
23
+ except AssertionError as exc:
24
+ raise NoCallableConstructError(func) from exc
25
+ else:
26
+ # Since we want to give detailed sub-failure diax in case of BEFOREANDAFTER,
27
+ # economisng on the ifs below is tricky.
28
+ if when == APRIORI:
29
+ try:
30
+ assert eval(that)
31
+ except AssertionError as exc:
32
+ raise RequirementNotFulfilledError(that, when) from exc
33
+ else:
34
+ func(self, *pargs, **kwargs)
35
+
36
+ elif when == POSTMORTEM:
37
+ func(self, *pargs, **kwargs)
38
+ try:
39
+ assert eval(that)
40
+ except AssertionError as exc:
41
+ raise RequirementNotFulfilledError(that, when) from exc
42
+
43
+ elif when == BEFOREANDAFTER:
44
+ try:
45
+ assert eval(that)
46
+ except AssertionError as exc:
47
+ raise RequirementNotFulfilledError(that, when, APRIORI) from exc
48
+ else:
49
+ func(self, *pargs, **kwargs)
50
+ try:
51
+ assert eval(that)
52
+ except AssertionError as exc:
53
+ raise RequirementNotFulfilledError(that, when, POSTMORTEM) from exc
54
+
55
+ # We don't need an else clause; trying to enlist something that's not in the enum
56
+ # will be penalised with an AttributeError, and small typos will be healed with a
57
+ # suggestion as to what you might have meant.
58
+
59
+ return inner_wrapper
60
+
61
+ return func_wrapper
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: requiresthat
3
- Version: 2025.6.17.0
3
+ Version: 2025.6.18.1
4
4
  Summary: Support for requirements-assisted development
5
5
  Author-email: Ann T Ropea <bedhanger@gmx.de>
6
6
  License-Expression: MIT
@@ -1 +0,0 @@
1
- from ._requires import requires, RequirementNotFulfilledError, APRIORI, POSTMORTEM, BEFOREANDAFTER
@@ -1,15 +0,0 @@
1
- """Raise this when a requirement is found wanting"""
2
-
3
- import textwrap
4
-
5
- class RequirementNotFulfilledError(Exception):
6
-
7
- def __init__(self, that, when, msg=None):
8
- """Show a default or a user-provided message indicating that some condition is unmet"""
9
-
10
- self.default_msg = textwrap.dedent(f"""
11
- {that!r} ({when.name!r}) does not hold
12
- """).strip()
13
-
14
- # Call the base class' constructor to init the exception class
15
- super().__init__(msg or self.default_msg)
@@ -1,40 +0,0 @@
1
- """See the README file"""
2
-
3
- from typing import Optional, Callable
4
- from functools import wraps
5
-
6
- from ._when import When, APRIORI, POSTMORTEM, BEFOREANDAFTER
7
- from ._exceptions import RequirementNotFulfilledError
8
-
9
- def requires(that, when: When = APRIORI) -> Optional[Callable]:
10
- """Require <that> of the decoratee, and require it <when>"""
11
-
12
- def func_wrapper(func: Callable) -> Optional[Callable]:
13
- """First-level wrap the decoratee"""
14
-
15
- @wraps(func)
16
- def inner_wrapper(self, *pargs, **kwargs) -> Optional[Callable]:
17
- """Wrap the first-level wrapper
18
-
19
- The wrapping stops here...
20
- """
21
- try:
22
- if when == APRIORI:
23
- assert eval(that)
24
- # We can use a return here :-)
25
- return func(self, *pargs, **kwargs)
26
- elif when == POSTMORTEM:
27
- func(self, *pargs, **kwargs)
28
- assert eval(that)
29
- elif when == BEFOREANDAFTER:
30
- assert eval(that)
31
- func(self, *pargs, **kwargs)
32
- assert eval(that)
33
- # We don't need an else clause; trying to enlist something that's not in the enum
34
- # will be penalised with an AttributeError, and small typos will be healed with a
35
- # suggestion as to what you might have meant.
36
- except AssertionError as exc:
37
- raise RequirementNotFulfilledError(that, when) from exc
38
- return inner_wrapper
39
-
40
- return func_wrapper