Skip to content

Commit 36f636a

Browse files
tjhunterTim Hunter
andauthored
[109] Disallow passing arguments to data functions (#123)
* changes * doc * version bump * trying to change the size of headers Co-authored-by: Tim Hunter <tjhunter@cs.stanford.edu>
1 parent cb0067a commit 36f636a

File tree

14 files changed

+78
-19
lines changed

14 files changed

+78
-19
lines changed

dds/_annotations.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import Any, Callable, TypeVar, cast, Union
55

66
from ._api import keep as _keep
7-
from .structures import DDSPath
7+
from .structures import DDSPath, DDSErrorCode, DDSException
88

99
F = TypeVar("F", bound=Callable[..., Any])
1010

@@ -55,6 +55,16 @@ def function():
5555
def decorator_(func: F) -> F:
5656
@functools.wraps(func)
5757
def wrapper(*args, **kwargs):
58+
if len(args) > 0 or len(kwargs) > 0:
59+
raise DDSException(
60+
f"@data_function cannot be used with arguments. "
61+
f"Arguments were passed to the function {func}, but this function "
62+
f"also has a dds.data_function annotation, which is not allowed (see "
63+
f"user guide of DDS). "
64+
f"Suggestion: write a wrapper function that does not take arguments itself, "
65+
f"or use dds.keep to pass arguments",
66+
DDSErrorCode.ARG_IN_DATA_FUNCTION,
67+
)
5868
return _keep(path, func, *args, **kwargs)
5969

6070
return cast(F, wrapper)

dds/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version = "0.7.3"
1+
version = "0.8.0"

dds/fun_args.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,19 @@ def get_arg_ctx(
168168
elif p.kind == Parameter.VAR_KEYWORD:
169169
# kwargs: for now, just ignored
170170
h = None
171+
elif p.kind == Parameter.POSITIONAL_OR_KEYWORD:
172+
# We are expecting a positional arguments, but no positional arguments
173+
# was provided. This is a programming error on the user side.
174+
raise DDSException(
175+
f"Missing argument {n} for function {f}. "
176+
f"DDS detected that the function {f} is missing the argument "
177+
f"{n} of type {p.kind}. This would trigger an error during the "
178+
f"execution of the code, aborting."
179+
)
171180
else:
172181
raise NotImplementedError(
173182
f"Cannot deal with argument name {n} of function {f}:"
174-
f"The argument kind {p.kind} is not understood (see exact definition in"
183+
f"The argument kind {p.kind} is not understood (see exact definition in "
175184
f"the module {Parameter}). Suggestion: your function is probably "
176185
f"using non-standard arguments. Use arguments of a simpler sort "
177186
f"(no kargs or kwargs). "

dds/structures.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class DDSErrorCode(IntEnum):
5555
OBJECT_PATH_NOT_FOUND = 12
5656
CONSTRUCT_NOT_SUPPORTED = 13
5757
STORE_PATH_NOT_SUPPORTED = 14
58+
ARG_IN_DATA_FUNCTION = 15
5859

5960

6061
class DDSException(BaseException):

dds_tests/test_annot_basic.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import dds
22
import pytest
3-
from .utils import cleandir, Counter, spath
3+
from .utils import cleandir, Counter
4+
from dds.structures import DDSException, DDSErrorCode
45

56
_ = cleandir
67

@@ -30,3 +31,22 @@ def test():
3031
assert _c.value == 1
3132
assert dds.eval(f1) == "a"
3233
assert _c.value == 1
34+
35+
36+
@dds.data_function("/p")
37+
def f2(x):
38+
return "a"
39+
40+
41+
def f2_1():
42+
f2(3)
43+
44+
45+
@pytest.mark.usefixtures("cleandir")
46+
def test_args():
47+
with pytest.raises(DDSException) as e:
48+
f2(3)
49+
assert e.value.error_code == DDSErrorCode.ARG_IN_DATA_FUNCTION
50+
with pytest.raises(DDSException) as e:
51+
dds.eval(f2_1)
52+
assert e.value.error_code == DDSErrorCode.ARG_IN_DATA_FUNCTION

doc_source/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ A number of small improvements in ergonomics to this release:
1212
* the error messages are more complete and include more contextual information
1313
* more types are supported by default during the analysis phase: lists, dictionaries,
1414
dates (`datetime` objects), arbitrary named tuples and arbitrary data classes.
15+
* the input for `@data_function` has been tightened to reflect the fact that data functions
16+
should not take arguments (`dds.keep` should be used instead). Passing arguments
17+
now triggers an error.
1518

1619
## v0.7.2
1720

doc_source/user_guide.ipynb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"cell_type": "markdown",
4242
"metadata": {},
4343
"source": [
44-
"## User guide\n",
44+
"# User guide\n",
4545
"\n",
4646
"The `dds` package solves the data integration problem in data science codebases. By using the `dds` package, you can safely assume that:\n",
4747
"\n",
@@ -286,7 +286,7 @@
286286
"As we said, the `data_function` annotation requires little code change but only works for functions that do not have arguments. How to deal with more complicated functions?\n",
287287
"This is the object of the next section.\n",
288288
"\n",
289-
"## Functions with arguments: keep() and eval()\n",
289+
"# Functions with arguments: keep() and eval()\n",
290290
"\n",
291291
"`dds` can also wrap functions that have arguments using the `dds.keep()` function. Here is a simple example, in which the `hello` function expects an extra word to be provided:"
292292
]
@@ -405,7 +405,7 @@
405405
"cell_type": "markdown",
406406
"metadata": {},
407407
"source": [
408-
"## Indirect references: load()\n",
408+
"# Indirect references: load()\n",
409409
"\n",
410410
"So far, we have seen only one way to access data: using `dds.keep` (or its shortcut `@data_function`). \n",
411411
"It is not always convenient to refer to the data function that created the piece of data in the first place.\n",

docs/changelog/changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ A number of small improvements in ergonomics to this release:
1212
* the error messages are more complete and include more contextual information
1313
* more types are supported by default during the analysis phase: lists, dictionaries,
1414
dates (`datetime` objects), arbitrary named tuples and arbitrary data classes.
15+
* the input for `@data_function` has been tightened to reflect the fact that data functions
16+
should not take arguments (`dds.keep` should be used instead). Passing arguments
17+
now triggers an error.
1518

1619
## v0.7.2
1720

docs/changelog/index.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ <h2 id="v080-unreleased">v0.8.0 (unreleased)</h2>
142142
<li>the error messages are more complete and include more contextual information</li>
143143
<li>more types are supported by default during the analysis phase: lists, dictionaries,
144144
dates (<code>datetime</code> objects), arbitrary named tuples and arbitrary data classes.</li>
145+
<li>the input for <code>@data_function</code> has been tightened to reflect the fact that data functions
146+
should not take arguments (<code>dds.keep</code> should be used instead). Passing arguments
147+
now triggers an error.</li>
145148
</ul>
146149
<h2 id="v072">v0.7.2</h2>
147150
<p>Small usability fixes in this release:</p>

docs/dds-reference/index.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,16 @@ <h2 class="doc doc-heading" id="dds._annotations.data_function">
198198
<span class="k">def</span> <span class="nf">decorator_</span><span class="p">(</span><span class="n">func</span><span class="p">:</span> <span class="n">F</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">F</span><span class="p">:</span>
199199
<span class="nd">@functools</span><span class="o">.</span><span class="n">wraps</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
200200
<span class="k">def</span> <span class="nf">wrapper</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
201+
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
202+
<span class="k">raise</span> <span class="n">DDSException</span><span class="p">(</span>
203+
<span class="sa">f</span><span class="s2">"@data_function cannot be used with arguments. "</span>
204+
<span class="sa">f</span><span class="s2">"Arguments were passed to the function </span><span class="si">{</span><span class="n">func</span><span class="si">}</span><span class="s2">, but this function "</span>
205+
<span class="sa">f</span><span class="s2">"also has a dds.data_function annotation, which is not allowed (see "</span>
206+
<span class="sa">f</span><span class="s2">"user guide of DDS). "</span>
207+
<span class="sa">f</span><span class="s2">"Suggestion: write a wrapper function that does not take arguments itself, "</span>
208+
<span class="sa">f</span><span class="s2">"or use dds.keep to pass arguments"</span><span class="p">,</span>
209+
<span class="n">DDSErrorCode</span><span class="o">.</span><span class="n">ARG_IN_DATA_FUNCTION</span><span class="p">,</span>
210+
<span class="p">)</span>
201211
<span class="k">return</span> <span class="n">_keep</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
202212

203213
<span class="k">return</span> <span class="n">cast</span><span class="p">(</span><span class="n">F</span><span class="p">,</span> <span class="n">wrapper</span><span class="p">)</span>

0 commit comments

Comments
 (0)