Skip to content

Commit

Permalink
#55 Fixed the empty input bug (#57)
Browse files Browse the repository at this point in the history
* #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 <[email protected]>

---------

Co-authored-by: Christoph Kuhnke <[email protected]>
  • Loading branch information
ahsimb and ckunki authored Oct 23, 2024
1 parent 13fa38a commit 90865de
Show file tree
Hide file tree
Showing 7 changed files with 257 additions and 165 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pytest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [ "3.8", "3.10" ]
python-version: [ "3.10", "3.11" ]
runs-on: ubuntu-latest

steps:
Expand Down
6 changes: 5 additions & 1 deletion doc/changes/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ Code name: tbd

### Bugs

n/a
* #55: Fixed bug when creating a `StandaloneMockContext` with empty input list

### Features

* #56: Made `script_code_wrapper_function` parameter of the `MockMetaData` optional.
47 changes: 26 additions & 21 deletions exasol_udf_mock_python/mock_context.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import List, Tuple, Iterator, Iterable, Any, Optional, Union
from collections.abc import Sized
from functools import wraps

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


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

if isinstance(inp, Iterable) and not isinstance(inp, str):
row1 = next(iter(inp))
if isinstance(row1, Iterable) and not isinstance(row1, str):
return inp
else:
return [inp]
else:
return [(inp,)]
if inp is not None:
if (not isinstance(inp, Iterable)) or isinstance(inp, str):
return [(inp,)]
try:
row1 = next(iter(inp))
if (not isinstance(row1, Iterable)) or isinstance(row1, str):
return [inp]
elif not isinstance(inp, Sized):
return list(inp)
else:
return inp
except StopIteration:
pass
return [tuple()]


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

i = 0
df = None
dfs: list[pd.DataFrame] = []
while num_rows == 'all' or i < num_rows:
df_current = pd.DataFrame.from_records(
[self._data[start_col:]], columns=columns_)
if df is None:
df = df_current
else:
df = df.append(df_current)
dfs.append(pd.DataFrame.from_records(
[self._data[start_col:]], columns=columns_))
if not self.next():
break
i += 1
if df is not None:
df = df.reset_index(drop=True)
return df
if dfs:
df = pd.concat(dfs, ignore_index=True)
df.reset_index(inplace=True, drop=True)
return df
return None

def __getattr__(self, name):
return None if self._data is None else self._data[self._name_position_map[name]]
Expand Down
3 changes: 2 additions & 1 deletion exasol_udf_mock_python/mock_meta_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ def __init__(
self._current_user = current_user
self._current_schema = current_schema
self._scope_user = scope_user
self._script_code = self._extract_script_code(script_code_wrapper_function)
self._script_code = (None if script_code_wrapper_function is None
else self._extract_script_code(script_code_wrapper_function))
self._connection_id = connection_id
self._database_name = database_name
self._database_version = database_version
Expand Down
Loading

0 comments on commit 90865de

Please sign in to comment.