diff --git a/MANIFEST.in b/MANIFEST.in index 6458d5778..71473c2c3 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,7 @@ graft src/runtime prune src/runtime/obj prune src/runtime/bin +include src/pythonnet.snk include Directory.Build.* include pythonnet.sln include version.txt diff --git a/pyproject.toml b/pyproject.toml index 5ee89d3b7..39c7c14fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ license = {text = "MIT"} readme = "README.rst" dependencies = [ - "clr_loader>=0.1.7" + "clr_loader>=0.2.2,<0.3.0" ] classifiers = [ diff --git a/pythonnet/__init__.py b/pythonnet/__init__.py index 9876a0bec..2cde01233 100644 --- a/pythonnet/__init__.py +++ b/pythonnet/__init__.py @@ -1,12 +1,12 @@ import sys from pathlib import Path -from typing import Dict, Optional, Union +from typing import Dict, Optional, Union, Any import clr_loader __all__ = ["set_runtime", "set_runtime_from_env", "load"] _RUNTIME: Optional[clr_loader.Runtime] = None -_LOADER_ASSEMBLY: Optional[clr_loader.wrappers.Assembly] = None +_LOADER_ASSEMBLY: Optional[clr_loader.Assembly] = None _LOADED: bool = False @@ -27,6 +27,15 @@ def set_runtime(runtime: Union[clr_loader.Runtime, str], **params: str) -> None: _RUNTIME = runtime +def get_runtime_info() -> Optional[clr_loader.RuntimeInfo]: + """Retrieve information on the configured runtime""" + + if _RUNTIME is None: + return None + else: + return _RUNTIME.info() + + def _get_params_from_env(prefix: str) -> Dict[str, str]: from os import environ @@ -43,9 +52,11 @@ def _get_params_from_env(prefix: str) -> Dict[str, str]: def _create_runtime_from_spec( - spec: str, params: Optional[Dict[str, str]] = None + spec: str, params: Optional[Dict[str, Any]] = None ) -> clr_loader.Runtime: + was_default = False if spec == "default": + was_default = True if sys.platform == "win32": spec = "netfx" else: @@ -53,14 +64,29 @@ def _create_runtime_from_spec( params = params or _get_params_from_env(spec) - if spec == "netfx": - return clr_loader.get_netfx(**params) - elif spec == "mono": - return clr_loader.get_mono(**params) - elif spec == "coreclr": - return clr_loader.get_coreclr(**params) - else: - raise RuntimeError(f"Invalid runtime name: '{spec}'") + try: + if spec == "netfx": + return clr_loader.get_netfx(**params) + elif spec == "mono": + return clr_loader.get_mono(**params) + elif spec == "coreclr": + return clr_loader.get_coreclr(**params) + else: + raise RuntimeError(f"Invalid runtime name: '{spec}'") + except Exception as exc: + if was_default: + raise RuntimeError( + f"""Failed to create a default .NET runtime, which would + have been "{spec}" on this system. Either install a + compatible runtime or configure it explicitly via + `set_runtime` or the `PYTHONNET_*` environment variables + (see set_runtime_from_env).""" + ) from exc + else: + raise RuntimeError( + f"""Failed to create a .NET runtime ({spec}) using the + parameters {params}.""" + ) from exc def set_runtime_from_env() -> None: @@ -85,9 +111,7 @@ def set_runtime_from_env() -> None: set_runtime(runtime) -def load( - runtime: Union[clr_loader.Runtime, str, None] = None, **params: str -) -> None: +def load(runtime: Union[clr_loader.Runtime, str, None] = None, **params: str) -> None: """Load Python.NET in the specified runtime The same parameters as for `set_runtime` can be used. By default, @@ -109,9 +133,9 @@ def load( dll_path = Path(__file__).parent / "runtime" / "Python.Runtime.dll" - _LOADER_ASSEMBLY = _RUNTIME.get_assembly(str(dll_path)) + _LOADER_ASSEMBLY = assembly = _RUNTIME.get_assembly(str(dll_path)) + func = assembly.get_function("Python.Runtime.Loader.Initialize") - func = _LOADER_ASSEMBLY["Python.Runtime.Loader.Initialize"] if func(b"") != 0: raise RuntimeError("Failed to initialize Python.Runtime.dll") @@ -125,12 +149,12 @@ def unload() -> None: global _RUNTIME, _LOADER_ASSEMBLY if _LOADER_ASSEMBLY is not None: - func = _LOADER_ASSEMBLY["Python.Runtime.Loader.Shutdown"] + func = _LOADER_ASSEMBLY.get_function("Python.Runtime.Loader.Shutdown") if func(b"full_shutdown") != 0: raise RuntimeError("Failed to call Python.NET shutdown") _LOADER_ASSEMBLY = None if _RUNTIME is not None: - # TODO: Add explicit `close` to clr_loader + _RUNTIME.shutdown() _RUNTIME = None diff --git a/tests/conftest.py b/tests/conftest.py index fcd1d224a..e61e3680e 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -53,10 +53,12 @@ def pytest_configure(config): runtime_params = {} if runtime_opt == "coreclr": - fw = "net6.0" - runtime_params["runtime_config"] = str( - bin_path / "Python.Test.runtimeconfig.json" - ) + # This is optional now: + # + # fw = "net6.0" + # runtime_params["runtime_config"] = str( + # bin_path / "Python.Test.runtimeconfig.json" + # ) collect_ignore.append("domain_tests/test_domain_reload.py") else: domain_tests_dir = cwd / "domain_tests" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy