-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43 from ma-sadeghi/fix_ipynb_bug_redo
Fix ipynb bug [REDO]
- Loading branch information
Showing
5 changed files
with
155 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
from typing import TYPE_CHECKING | ||
|
||
if TYPE_CHECKING: | ||
from typing import List | ||
|
||
from pytest_split.algorithms import TestGroup | ||
|
||
|
||
def ensure_ipynb_compatibility(group: "TestGroup", items: list) -> None: | ||
""" | ||
Ensures that group doesn't contain partial IPy notebook cells. | ||
``pytest-split`` might, in principle, break up the cells of an | ||
IPython notebook into different test groups, in which case the tests | ||
most likely fail (for starters, libraries are imported in Cell 0, so | ||
all subsequent calls to the imported libraries in the following cells | ||
will raise ``NameError``). | ||
""" | ||
if not group.selected or not _is_ipy_notebook(group.selected[0].nodeid): | ||
return | ||
|
||
item_node_ids = [item.nodeid for item in items] | ||
|
||
# Deal with broken up notebooks at the beginning of the test group | ||
first = group.selected[0].nodeid | ||
siblings = _find_sibiling_ipynb_cells(first, item_node_ids) | ||
if first != siblings[0]: | ||
for item in list(group.selected): | ||
if item.nodeid in siblings: | ||
group.deselected.append(item) | ||
group.selected.remove(item) | ||
|
||
if not group.selected or not _is_ipy_notebook(group.selected[-1].nodeid): | ||
return | ||
|
||
# Deal with broken up notebooks at the end of the test group | ||
last = group.selected[-1].nodeid | ||
siblings = _find_sibiling_ipynb_cells(last, item_node_ids) | ||
if last != siblings[-1]: | ||
for item in list(group.deselected): | ||
if item.nodeid in siblings: | ||
group.deselected.remove(item) | ||
group.selected.append(item) | ||
|
||
|
||
def _find_sibiling_ipynb_cells( | ||
ipynb_node_id: str, item_node_ids: "List[str]" | ||
) -> "List[str]": | ||
""" | ||
Returns all sibiling IPyNb cells given an IPyNb cell nodeid. | ||
""" | ||
fpath = ipynb_node_id.split("::")[0] | ||
return [item for item in item_node_ids if fpath in item] | ||
|
||
|
||
def _is_ipy_notebook(node_id: str) -> bool: | ||
""" | ||
Returns True if node_id is an IPython notebook, otherwise False. | ||
""" | ||
fpath = node_id.split("::")[0] | ||
return fpath.endswith(".ipynb") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
from collections import namedtuple | ||
|
||
import pytest | ||
|
||
from pytest_split.algorithms import Algorithms | ||
from pytest_split.ipynb_compatibility import ensure_ipynb_compatibility | ||
|
||
item = namedtuple("item", "nodeid") | ||
|
||
|
||
class TestIPyNb: | ||
@pytest.mark.parametrize("algo_name", ["duration_based_chunks"]) | ||
def test_ensure_ipynb_compatibility(self, algo_name): | ||
durations = { | ||
"temp/nbs/test_1.ipynb::Cell 0": 1, | ||
"temp/nbs/test_1.ipynb::Cell 1": 1, | ||
"temp/nbs/test_1.ipynb::Cell 2": 1, | ||
"temp/nbs/test_2.ipynb::Cell 0": 3, | ||
"temp/nbs/test_2.ipynb::Cell 1": 5, | ||
"temp/nbs/test_2.ipynb::Cell 2": 1, | ||
"temp/nbs/test_2.ipynb::Cell 3": 4, | ||
"temp/nbs/test_3.ipynb::Cell 0": 5, | ||
"temp/nbs/test_3.ipynb::Cell 1": 1, | ||
"temp/nbs/test_3.ipynb::Cell 2": 1, | ||
"temp/nbs/test_3.ipynb::Cell 3": 2, | ||
"temp/nbs/test_3.ipynb::Cell 4": 1, | ||
"temp/nbs/test_4.ipynb::Cell 0": 1, | ||
"temp/nbs/test_4.ipynb::Cell 1": 1, | ||
"temp/nbs/test_4.ipynb::Cell 2": 3, | ||
} | ||
items = [item(x) for x in durations.keys()] | ||
algo = Algorithms[algo_name].value | ||
groups = algo(splits=3, items=items, durations=durations) | ||
|
||
assert groups[0].selected == [ | ||
item(nodeid="temp/nbs/test_1.ipynb::Cell 0"), | ||
item(nodeid="temp/nbs/test_1.ipynb::Cell 1"), | ||
item(nodeid="temp/nbs/test_1.ipynb::Cell 2"), | ||
item(nodeid="temp/nbs/test_2.ipynb::Cell 0"), | ||
item(nodeid="temp/nbs/test_2.ipynb::Cell 1"), | ||
] | ||
assert groups[1].selected == [ | ||
item(nodeid="temp/nbs/test_2.ipynb::Cell 2"), | ||
item(nodeid="temp/nbs/test_2.ipynb::Cell 3"), | ||
item(nodeid="temp/nbs/test_3.ipynb::Cell 0"), | ||
item(nodeid="temp/nbs/test_3.ipynb::Cell 1"), | ||
] | ||
assert groups[2].selected == [ | ||
item(nodeid="temp/nbs/test_3.ipynb::Cell 2"), | ||
item(nodeid="temp/nbs/test_3.ipynb::Cell 3"), | ||
item(nodeid="temp/nbs/test_3.ipynb::Cell 4"), | ||
item(nodeid="temp/nbs/test_4.ipynb::Cell 0"), | ||
item(nodeid="temp/nbs/test_4.ipynb::Cell 1"), | ||
item(nodeid="temp/nbs/test_4.ipynb::Cell 2"), | ||
] | ||
|
||
ensure_ipynb_compatibility(groups[0], items) | ||
assert groups[0].selected == [ | ||
item(nodeid="temp/nbs/test_1.ipynb::Cell 0"), | ||
item(nodeid="temp/nbs/test_1.ipynb::Cell 1"), | ||
item(nodeid="temp/nbs/test_1.ipynb::Cell 2"), | ||
item(nodeid="temp/nbs/test_2.ipynb::Cell 0"), | ||
item(nodeid="temp/nbs/test_2.ipynb::Cell 1"), | ||
item(nodeid="temp/nbs/test_2.ipynb::Cell 2"), | ||
item(nodeid="temp/nbs/test_2.ipynb::Cell 3"), | ||
] | ||
|
||
ensure_ipynb_compatibility(groups[1], items) | ||
assert groups[1].selected == [ | ||
item(nodeid="temp/nbs/test_3.ipynb::Cell 0"), | ||
item(nodeid="temp/nbs/test_3.ipynb::Cell 1"), | ||
item(nodeid="temp/nbs/test_3.ipynb::Cell 2"), | ||
item(nodeid="temp/nbs/test_3.ipynb::Cell 3"), | ||
item(nodeid="temp/nbs/test_3.ipynb::Cell 4"), | ||
] | ||
|
||
ensure_ipynb_compatibility(groups[2], items) | ||
assert groups[2].selected == [ | ||
item(nodeid="temp/nbs/test_4.ipynb::Cell 0"), | ||
item(nodeid="temp/nbs/test_4.ipynb::Cell 1"), | ||
item(nodeid="temp/nbs/test_4.ipynb::Cell 2"), | ||
] |