Skip to content

Commit 90865de

Browse files
ahsimbckunki
andauthored
#55 Fixed the empty input bug (#57)
* #55 Fixed the empty input bug * #55 Updated poetry.lock * #55 Updated poetry.lock * #55 Fixed the pandas append issue * Apply suggestions from code review Co-authored-by: Christoph Kuhnke <christoph.kuhnke@exasol.com> --------- Co-authored-by: Christoph Kuhnke <christoph.kuhnke@exasol.com>
1 parent 13fa38a commit 90865de

File tree

7 files changed

+257
-165
lines changed

7 files changed

+257
-165
lines changed

.github/workflows/pytest.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
strategy:
88
fail-fast: false
99
matrix:
10-
python-version: [ "3.8", "3.10" ]
10+
python-version: [ "3.10", "3.11" ]
1111
runs-on: ubuntu-latest
1212

1313
steps:

doc/changes/unreleased.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ Code name: tbd
66

77
### Bugs
88

9-
n/a
9+
* #55: Fixed bug when creating a `StandaloneMockContext` with empty input list
10+
11+
### Features
12+
13+
* #56: Made `script_code_wrapper_function` parameter of the `MockMetaData` optional.

exasol_udf_mock_python/mock_context.py

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from typing import List, Tuple, Iterator, Iterable, Any, Optional, Union
2+
from collections.abc import Sized
23
from functools import wraps
34

45
import pandas as pd
@@ -133,24 +134,30 @@ def emit(self, *args) -> None:
133134
self._current_context.emit(*args)
134135

135136

136-
def get_scalar_input(inp: Any) -> Iterable[Tuple[Any, ...]]:
137+
def get_scalar_input(inp: Any) -> Iterable[Iterable[Any]]:
137138
"""
138139
Figures out if the SCALAR parameters are provided as a scalar value or a tuple
139140
and also if there is a wrapping container around.
140-
Unless the parameters are already in a wrapping container returns parameters as a tuple wrapped
141-
into a one-item list, e.g [(param1[, param2, ...)]. Otherwise, returns the original input.
141+
Unless the parameters are already in a wrapping Sized container, returns parameters as an iterable
142+
wrapped into a one-item list, e.g [(param1, [param2, ...])]. Otherwise, returns the original input.
142143
143144
:param inp: Input parameters.
144145
"""
145146

146-
if isinstance(inp, Iterable) and not isinstance(inp, str):
147-
row1 = next(iter(inp))
148-
if isinstance(row1, Iterable) and not isinstance(row1, str):
149-
return inp
150-
else:
151-
return [inp]
152-
else:
153-
return [(inp,)]
147+
if inp is not None:
148+
if (not isinstance(inp, Iterable)) or isinstance(inp, str):
149+
return [(inp,)]
150+
try:
151+
row1 = next(iter(inp))
152+
if (not isinstance(row1, Iterable)) or isinstance(row1, str):
153+
return [inp]
154+
elif not isinstance(inp, Sized):
155+
return list(inp)
156+
else:
157+
return inp
158+
except StopIteration:
159+
pass
160+
return [tuple()]
154161

155162

156163
class StandaloneMockContext(UDFContext):
@@ -205,20 +212,18 @@ def get_dataframe(self, num_rows='all', start_col=0):
205212
columns_ = [column.name for column in self._metadata.input_columns[start_col:]]
206213

207214
i = 0
208-
df = None
215+
dfs: list[pd.DataFrame] = []
209216
while num_rows == 'all' or i < num_rows:
210-
df_current = pd.DataFrame.from_records(
211-
[self._data[start_col:]], columns=columns_)
212-
if df is None:
213-
df = df_current
214-
else:
215-
df = df.append(df_current)
217+
dfs.append(pd.DataFrame.from_records(
218+
[self._data[start_col:]], columns=columns_))
216219
if not self.next():
217220
break
218221
i += 1
219-
if df is not None:
220-
df = df.reset_index(drop=True)
221-
return df
222+
if dfs:
223+
df = pd.concat(dfs, ignore_index=True)
224+
df.reset_index(inplace=True, drop=True)
225+
return df
226+
return None
222227

223228
def __getattr__(self, name):
224229
return None if self._data is None else self._data[self._name_position_map[name]]

exasol_udf_mock_python/mock_meta_data.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ def __init__(
4242
self._current_user = current_user
4343
self._current_schema = current_schema
4444
self._scope_user = scope_user
45-
self._script_code = self._extract_script_code(script_code_wrapper_function)
45+
self._script_code = (None if script_code_wrapper_function is None
46+
else self._extract_script_code(script_code_wrapper_function))
4647
self._connection_id = connection_id
4748
self._database_name = database_name
4849
self._database_version = database_version

0 commit comments

Comments
 (0)