diff --git a/docs/source/conf.py b/docs/source/conf.py index cae9f45..c455c56 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -14,10 +14,14 @@ from importlib.metadata import version from pathlib import Path from typing import TYPE_CHECKING +from typing import Any +from typing import cast import pytask_parallel if TYPE_CHECKING: + from collections.abc import Callable + import sphinx # ty: ignore[unresolved-import] @@ -100,7 +104,9 @@ # Linkcode, based on numpy doc/source/conf.py -def linkcode_resolve(domain: str, info: dict[str, str]) -> str | None: # noqa: C901 +def linkcode_resolve( # noqa: C901, PLR0911 + domain: str, info: dict[str, str] +) -> str | None: """Determine the URL corresponding to Python object.""" if domain != "py": return None @@ -122,29 +128,35 @@ def linkcode_resolve(domain: str, info: dict[str, str]) -> str | None: # noqa: except AttributeError: # noqa: PERF203 return None - try: - fn = inspect.getsourcefile(inspect.unwrap(obj)) # ty: ignore[invalid-argument-type] - except TypeError: - try: # property - fn = inspect.getsourcefile(inspect.unwrap(obj.fget)) # ty: ignore[possibly-unbound-attribute,invalid-argument-type] - except (AttributeError, TypeError): - fn = None + obj_for_source = obj if callable(obj) else getattr(obj, "fget", None) + if not callable(obj_for_source): + return None + + fn = inspect.getsourcefile( + inspect.unwrap(cast("Callable[..., Any]", obj_for_source)) + ) if not fn: return None try: source, lineno = inspect.getsourcelines(obj) except TypeError: - try: # property - source, lineno = inspect.getsourcelines(obj.fget) # ty: ignore[possibly-unbound-attribute] - except (AttributeError, TypeError): + fget = getattr(obj, "fget", None) + if fget is None: lineno = None + else: + try: + source, lineno = inspect.getsourcelines(fget) + except TypeError: + lineno = None except OSError: lineno = None linespec = f"#L{lineno}-L{lineno + len(source) - 1}" if lineno else "" - fn = os.path.relpath(fn, start=Path(pytask_parallel.__file__).parent) # ty: ignore[invalid-argument-type] + package_file = pytask_parallel.__file__ + package_root = Path(package_file).parent if package_file else Path.cwd() + fn = os.path.relpath(fn, start=package_root) if "+" in pytask_parallel.__version__: return f"https://github.com/pytask-dev/pytask-parallel/blob/main/src/pytask_parallel/{fn}{linespec}" diff --git a/src/pytask_parallel/execute.py b/src/pytask_parallel/execute.py index f7cea9f..6eb6465 100644 --- a/src/pytask_parallel/execute.py +++ b/src/pytask_parallel/execute.py @@ -6,6 +6,7 @@ import time from typing import TYPE_CHECKING from typing import Any +from typing import cast import cloudpickle from _pytask.node_protocols import PPathNode @@ -209,7 +210,7 @@ def pytask_execute_task(session: Session, task: PTask) -> Future[WrapperResult]: task_module = get_module(task.function, getattr(task, "path", None)) cloudpickle.register_pickle_by_value(task_module) - return wrapper_func.submit( # ty: ignore[possibly-unbound-attribute,invalid-return-type] + return cast("Any", wrapper_func).submit( task=task, console_options=console.options, kwargs=kwargs, diff --git a/src/pytask_parallel/wrappers.py b/src/pytask_parallel/wrappers.py index 7cb28f8..d483d3c 100644 --- a/src/pytask_parallel/wrappers.py +++ b/src/pytask_parallel/wrappers.py @@ -13,6 +13,7 @@ from pathlib import Path from typing import TYPE_CHECKING from typing import Any +from typing import cast from attrs import define from pytask import PNode @@ -35,6 +36,7 @@ from pytask_parallel.utils import CoiledFunction if TYPE_CHECKING: + from collections.abc import Callable from types import TracebackType from pytask import Mark @@ -168,9 +170,11 @@ def wrap_task_in_process( # noqa: PLR0913 def rewrap_task_with_coiled_function(task: PTask) -> CoiledFunction: - return functools.wraps(wrap_task_in_process)( # ty: ignore[invalid-return-type] - CoiledFunction(wrap_task_in_process, **task.attributes["coiled_kwargs"]) # ty: ignore[invalid-argument-type] + wrapped = CoiledFunction(wrap_task_in_process, **task.attributes["coiled_kwargs"]) + decorated = functools.wraps(wrap_task_in_process)( + cast("Callable[..., Any]", wrapped) ) + return cast("CoiledFunction", decorated) def _raise_exception_on_breakpoint(*args: Any, **kwargs: Any) -> None: # noqa: ARG001 @@ -203,7 +207,7 @@ def _render_traceback_to_string( ) -> tuple[type[BaseException], BaseException, str]: """Process the exception and convert the traceback to a string.""" traceback = Traceback(exc_info, show_locals=show_locals) - segments = console.render(traceback, options=console_options) # ty: ignore[invalid-argument-type] + segments = console.render(cast("Any", traceback), options=console_options) text = "".join(segment.text for segment in segments) return (*exc_info[:2], text) # ty: ignore[invalid-return-type]