8000 Fixes for resolution of explicit allow_refs=False and async functions by philippjfr · Pull Request #865 · holoviz/param · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fixes for resolution of explicit allow_refs=False and async functions #865

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions param/parameterized.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def resolve_value(value):
resolve_value(value.step)
)
value = transform_reference(value)
if hasattr(value, '_dinfo'):
if hasattr(value, '_dinfo') or iscoroutinefunction(value):
value = eval_function_with_deps(value)
elif isinstance(value, Parameter):
value = getattr(value.owner, value.name)
Expand Down Expand Up @@ -3567,9 +3567,13 @@ def __param_inheritance(mcs, param_name, param):
callables[slot] = default_val
else:
10000 slot_values[slot] = default_val
elif slot == 'allow_refs' and not slot_values[slot]:
elif slot == 'allow_refs':
# Track Parameters that explicitly declared no refs
mcs._param__private.explicit_no_refs.append(param.name)
explicit_no_refs = mcs._param__private.explicit_no_refs
if param.allow_refs is False:
explicit_no_refs.append(param.name)
elif param.allow_refs is True and param.name in explicit_no_refs:
explicit_no_refs.remove(param.name)

# Now set the actual slot values
for slot, value in slot_values.items():
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ doc = [
tests = [
"coverage[toml]",
"pytest",
"pytest-asyncio",
]
tests-deser = [
"xlrd",
Expand All @@ -56,6 +57,7 @@ tests-deser = [
]
tests-examples = [
"pytest",
"pytest-asyncio",
"pytest-xdist",
"nbval",
"param[examples]",
Expand Down Expand Up @@ -218,6 +220,7 @@ filterwarnings = [
"error",
]
xfail_strict = "true"
asyncio_mode = "auto"

[tool.coverage.report]
omit = ["param/version.py"]
16 changes: 16 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import asyncio

import param
import pytest

param.parameterized.warnings_as_exceptions = True

def async_execute(func):
event_loop = asyncio.get_running_loop()
if event_loop.is_running():
asyncio.create_task(func())
else:
event_loop.run_until_complete(func())
return

@pytest.fixture
def dataframe():
Expand All @@ -12,3 +21,10 @@ def dataframe():
'float': [3.14, 6.28, 9.42],
'str': ['A', 'B', 'C']
}, index=[1, 2, 3], columns=['int', 'float', 'str'])

@pytest.fixture
def async_executor():
old_executor = param.parameterized.async_executor
param.parameterized.async_executor = async_execute
yield
param.parameterized.async_executor = old_executor
55 changes: 55 additions & 0 deletions tests/testrefs.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import asyncio

import param
import pytest

Expand All @@ -11,6 +13,15 @@ class Parameters(param.Parameterized):

string_list = param.List(default=[], item_type=str, allow_refs=True, nested_refs=True)

no_refs = param.Parameter(allow_refs=False)

class Subclass(Parameters):

no_refs = param.Parameter()

class SubclassOverride(Parameters):

no_refs = param.Parameter(allow_refs=True)

class Nested(param.Parameterized):

Expand All @@ -21,6 +32,15 @@ def string(self):
return self.subobject.string + '!'


def test_class_explicit_no_refs():
assert Parameters._param__private.explicit_no_refs == ['no_refs']

def test_subclass_explicit_no_refs():
assert Subclass._param__private.explicit_no_refs == ['no_refs']

def test_subclass_explicit_no_refs_override():
assert SubclassOverride._param__private.explicit_no_refs == []

def test_parameterized_warns_explicit_no_ref():
class ImplicitRefsParameters(param.Parameterized):
parameter = param.Parameter(default="string")
Expand Down Expand Up @@ -100,3 +120,38 @@ def test_nested_param_method_ref():
assert p2.string == 'string!'
p.string = 'new string'
assert p2.string == 'new string!'

async def test_async_function_ref(async_executor):
async def gen_strings():
await asyncio.sleep(0.02)
return 'string!'

p = Parameters(string=gen_strings)

await asyncio.sleep(0.1)
assert p.string == 'string!'

async def test_async_bind_ref(async_executor):
p = Parameters()

async def exclaim(string):
await asyncio.sleep(0.05)
return string + '!'

p2 = Parameters(string=bind(exclaim, p.param.string))
await asyncio.sleep(0.1)
assert p2.string == 'string!'
p.string = 'new string'
await asyncio.sleep(0.1)
assert p2.string == 'new string!'

async def test_async_generator_ref(async_executor):
async def gen_strings():
string = 'string'
for i in range(10):
yield string + '!' * i

p = Parameters(string=gen_strings)

await asyncio.sleep(0.1)
assert p.string == 'string!!!!!!!!!'
0