Skip to content

Commit

Permalink
#55 Fixed the empty input bug
Browse files Browse the repository at this point in the history
  • Loading branch information
ahsimb committed Oct 22, 2024
1 parent 13fa38a commit ef3958d
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 14 deletions.
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: Not possible to create StandaloneMockContext with empty input list

### Features

* #56: Made script_code_wrapper_function parameter of the MockMetaData optional.
29 changes: 18 additions & 11 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
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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ keywords = ['exasol', 'udf', 'mock', 'testing']
[tool.poetry.dependencies]
python = "^3.8"
pandas = "^1.4"
numpy = "^1.22"
numpy = ">=1.26.0"
dill = ">=0.3.7"

[tool.poetry.dev-dependencies]
Expand Down
15 changes: 15 additions & 0 deletions tests/test_mock_context_standalone.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ def test_attr_scalar(context_scalar_return):
assert context_scalar_return.t == 5


@pytest.mark.parametrize('inp', [None, [], [[]]])
def test_context_empty_input(inp):
meta_data = MockMetaData(
script_code_wrapper_function=udf_wrapper,
input_type='SCALAR',
input_columns=[],
output_type='RETURNS',
output_columns=[Column('t', int, 'INTEGER')]
)
_ = StandaloneMockContext(inp, meta_data)
# There is nothing to test here apart from successful creation of the
# context object. This internally has some checks that need to be passed.
pass


def test_next(context_set_emits):
assert context_set_emits.next()
assert context_set_emits.t1 == 6
Expand Down

0 comments on commit ef3958d

Please sign in to comment.