Skip to content

Commit

Permalink
fix python interpreter (#456)
Browse files Browse the repository at this point in the history
* fix python interpreter

* fix tests

* lint
  • Loading branch information
PythonFZ authored Dec 6, 2022
1 parent c8b2822 commit ce04730
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def test_example_func_dry_run(proj_path):
"--outs",
"test.txt",
(
f'{utils.get_python_interpreter()} -c "from test_single_function import '
f'{utils.config.interpreter} -c "from test_single_function import '
'example_func; example_func(exec_func=True)" '
),
]
Expand Down
5 changes: 3 additions & 2 deletions tests/unit_tests/core/test_core_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,9 @@ def test_write_graph():
"--outs",
"example.dat",
(
'python3 -c "from test_core_base import ExampleDVCOutsNode; '
"ExampleDVCOutsNode.load(name='ExampleDVCOutsNode').run_and_save()\" "
f'{utils.config.interpreter} -c "from test_core_base import'
" ExampleDVCOutsNode;"
" ExampleDVCOutsNode.load(name='ExampleDVCOutsNode').run_and_save()\" "
),
]

Expand Down
4 changes: 2 additions & 2 deletions tests/unit_tests/core/test_dvcgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def test_prepare_dvc_script():
"--deps",
"file.txt",
(
f'{utils.get_python_interpreter()} -c "from src.file import MyNode;'
f'{utils.config.interpreter} -c "from src.file import MyNode;'
' MyNode.load().run_and_save()" '
),
]
Expand Down Expand Up @@ -214,7 +214,7 @@ def test_prepare_dvc_script():
"--deps",
"src/file.py",
(
f'{utils.get_python_interpreter()} -c "from src.file import MyNode;'
f'{utils.config.interpreter} -c "from src.file import MyNode;'
' MyNode.load().run_and_save()" '
),
]
Expand Down
11 changes: 9 additions & 2 deletions tests/unit_tests/utils/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,16 @@ def test_check_type():
assert utils.check_type({"a": {"b": "c"}}, str, allow_dict=True)


def test_python_interpreter():
assert utils.get_python_interpreter() in ["python", "python3"]
def test_config_interpreter():
assert utils.config.interpreter in ["python", "python3"]


def test_module_to_path():
assert utils.module_to_path("src.module") == pathlib.Path("src", "module.py")


def test_config_change():
assert utils.config.lazy
with utils.config.updated_config(lazy=False):
assert not utils.config.lazy
assert utils.config.lazy
2 changes: 1 addition & 1 deletion zntrack/core/dvcgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def prepare_dvc_script(
if nb_name is not None:
script += ["--deps", utils.module_to_path(module).as_posix()]

import_str = f"""{utils.get_python_interpreter()} -c "from {module} import """
import_str = f"""{utils.config.interpreter} -c "from {module} import """
import_str += f"""{func_or_cls}; {func_or_cls}{call_args}" """
script += [import_str]
log.debug(f"dvc script: {' '.join([str(x) for x in script])}")
Expand Down
2 changes: 0 additions & 2 deletions zntrack/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
decode_dict,
deprecated,
encode_dict,
get_python_interpreter,
module_handler,
module_to_path,
run_dvc_cmd,
Expand All @@ -38,7 +37,6 @@
"exceptions",
Files.__name__,
"check_type",
"get_python_interpreter",
"run_dvc_cmd",
"FILE_DVC_TRACKED",
"VALUE_DVC_TRACKED",
Expand Down
28 changes: 28 additions & 0 deletions zntrack/utils/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
"""Description: Configuration File for ZnTrack."""
import contextlib
import dataclasses
import logging
import sys
import typing
from pathlib import Path


Expand All @@ -27,12 +30,19 @@ class Config:
runs. If you encounter any issues you can set it to logging.INFO for more in-depth
information. DEBUG level can produce a lot of useful information for more complex
issues.
interpreter: str|Path, default = None
Set the Python interpreter to be used for the 'dvc cmd'.
If None, ZnTrack will try to automatically determine the interpreter.
Use e.g. `config.interpreter=sys.executable` to use a specific version.
Note, that changing the command will also affect your graph, and you might
not be able to use the existing cache.
"""

nb_name: str = None
nb_class_path: Path = Path("src")
lazy: bool = True
allow_empty_loading: bool = False
interpreter: typing.Union[str, Path] = Path(sys.executable).name
_log_level: int = dataclasses.field(default=logging.INFO, init=False, repr=True)

@property
Expand All @@ -47,6 +57,24 @@ def log_level(self, value):
logger = logging.getLogger("zntrack")
logger.setLevel(self._log_level)

@contextlib.contextmanager
def updated_config(self, **kwargs) -> None:
"""Temporarily update the config.
Yields
------
Environment with temporarily changed config.
"""
state = {}
for key, value in kwargs.items():
state[key] = getattr(self, key)
setattr(self, key, value)
try:
yield
finally:
for key, value in state.items():
setattr(self, key, value)


@dataclasses.dataclass(frozen=True)
class Files:
Expand Down
30 changes: 0 additions & 30 deletions zntrack/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,36 +150,6 @@ def module_to_path(module: str, suffix=".py") -> pathlib.Path:
return pathlib.Path(*module.split(".")).with_suffix(suffix)


def get_python_interpreter() -> str:
"""Find the most suitable python interpreter.
Try to run subprocess check calls to see, which python interpreter
should be selected
Returns
-------
interpreter: str
Name of the python interpreter that works with subprocess calls
"""
for interpreter in ["python3", "python"]:
try:
subprocess.check_call(
[interpreter, "--version"],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
log.debug(f"Using command {interpreter} for dvc!")
return interpreter

except subprocess.CalledProcessError:
log.debug(f"{interpreter} is not working!")
except FileNotFoundError as err:
log.debug(err)
raise ValueError(
"Could not find a working python interpreter to work with subprocesses!"
)


def run_dvc_cmd(script):
"""Run the DVC script via subprocess calls.
Expand Down

3 comments on commit ce04730

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Report for Python 3.8

name min max mean stddev median iqr outliers ops rounds iterations
0 tests/benchmark/test_benchmark.py::test_NodeCollector_run_and_save 0.0002242 0.0007023 0.000277501 7.72384e-05 0.00023965 8.39e-05 9;3 3603.59 82 1
1 tests/benchmark/test_benchmark.py::test_InputOutput_load 0.0009065 0.0010814 0.000920459 1.30844e-05 0.000916899 1.2125e-05 69;17 1086.41 585 1
2 tests/benchmark/test_benchmark.py::test_InputOutput_load_lazy 0.0009071 0.0011415 0.00092293 1.95495e-05 0.000918899 1.23e-05 30;27 1083.51 599 1
3 tests/benchmark/test_benchmark.py::test_InputOutput_write_graph 0.0013172 0.0017256 0.00138027 4.13722e-05 0.00137405 4.12995e-05 87;22 724.496 464 1
4 tests/benchmark/test_benchmark.py::test_InputOutput_run_and_save 0.0013478 0.0038222 0.00143513 0.000124772 0.0014139 5.16e-05 29;53 696.8 571 1
5 tests/benchmark/test_benchmark.py::test_NodeCollector_load 0.0015653 0.0017948 0.00159204 1.70963e-05 0.00159 1.595e-05 56;11 628.125 420 1
6 tests/benchmark/test_benchmark.py::test_NodeCollector_load_lazy 0.0015729 0.0017288 0.00159626 1.46587e-05 0.0015944 1.50495e-05 75;5 626.463 416 1
7 tests/benchmark/test_benchmark.py::test_NodeCollector_write_graph 1.30781 1.38541 1.35158 0.0374277 1.37021 0.0686681 1;0 0.739875 5 1

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Report for Python 3.10

name min max mean stddev median iqr outliers ops rounds iterations
0 tests/benchmark/test_benchmark.py::test_NodeCollector_run_and_save 0.000379317 0.000979744 0.000504145 0.00013174 0.00046037 0.000140206 10;6 1983.55 74 1
1 tests/benchmark/test_benchmark.py::test_InputOutput_load_lazy 0.000995742 0.0049175 0.00123653 0.000332363 0.00113855 0.00010498 38;68 808.712 611 1
2 tests/benchmark/test_benchmark.py::test_InputOutput_load 0.00109325 0.00642349 0.00122096 0.000312871 0.00113455 9.0903e-05 46;80 819.026 718 1
3 tests/benchmark/test_benchmark.py::test_NodeCollector_load 0.00177958 0.00360416 0.00191772 0.000190934 0.00185158 9.8505e-05 39;46 521.454 410 1
4 tests/benchmark/test_benchmark.py::test_NodeCollector_load_lazy 0.00179868 0.00497322 0.00208547 0.000449032 0.00189263 0.000306914 58;51 479.507 466 1
5 tests/benchmark/test_benchmark.py::test_InputOutput_write_graph 0.00191579 0.00627848 0.00209069 0.000295649 0.00200699 0.00011328 28;45 478.31 355 1
6 tests/benchmark/test_benchmark.py::test_InputOutput_run_and_save 0.00197589 0.00825937 0.00223874 0.000463157 0.0021283 0.000151606 23;57 446.68 532 1
7 tests/benchmark/test_benchmark.py::test_NodeCollector_write_graph 1.50963 1.71379 1.58625 0.0837366 1.59695 0.117252 1;0 0.630418 5 1

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Report for Python 3.9

name min max mean stddev median iqr outliers ops rounds iterations
0 tests/benchmark/test_benchmark.py::test_NodeCollector_run_and_save 0.000410003 0.00402733 0.000808694 0.000716504 0.000555154 0.000384503 4;4 1236.56 58 1
1 tests/benchmark/test_benchmark.py::test_InputOutput_load_lazy 0.00107951 0.00995527 0.0013954 0.000456524 0.00132651 0.000186402 21;31 716.638 525 1
2 tests/benchmark/test_benchmark.py::test_InputOutput_load 0.00124021 0.00716905 0.00155305 0.000651874 0.00138711 0.000271677 21;32 643.892 441 1
3 tests/benchmark/test_benchmark.py::test_NodeCollector_load 0.00173542 0.0142803 0.00229936 0.000867374 0.00219918 0.000295291 7;12 434.903 364 1
4 tests/benchmark/test_benchmark.py::test_NodeCollector_load_lazy 0.00177431 0.00528334 0.00229383 0.000373451 0.00221832 0.000281651 44;18 435.952 301 1
5 tests/benchmark/test_benchmark.py::test_InputOutput_write_graph 0.00202241 0.00741365 0.00251894 0.000585399 0.00238682 0.000319827 21;23 396.993 317 1
6 tests/benchmark/test_benchmark.py::test_InputOutput_run_and_save 0.00207601 0.00843646 0.0026861 0.000647167 0.00251732 0.000374803 31;31 372.287 412 1
7 tests/benchmark/test_benchmark.py::test_NodeCollector_write_graph 1.60042 2.15061 1.88383 0.23123 1.97816 0.375797 2;0 0.530835 5 1

Please sign in to comment.