============================= test session starts ============================== platform linux -- Python 3.13.3, pytest-8.3.5, pluggy-1.6.0 -- /home/XXXXXXXXX/anaconda3/envs/metocean-api/bin/python3.13 cachedir: .pytest_cache rootdir: /mnt/c/XXXXXXXXX/Documents/GIT/metocean-api configfile: pyproject.toml plugins: cov-6.1.1 collecting ... collected 17 items tests/test_combine_data.py::test_combine_data PASSED [ 5%] tests/test_extract_data.py::test_extract_nora3_wind PASSED [ 11%] tests/test_extract_data.py::test_download_of_temporary_files PASSED [ 17%] tests/test_extract_data.py::test_extract_nora3_wave PASSED [ 23%] tests/test_extract_data.py::test_nora3_wind_wave_combined PASSED [ 29%] tests/test_extract_data.py::test_extract_nora3_fp ----> Here we got a segmentation fault ============================= test session starts ============================== platform linux -- Python 3.13.3, pytest-8.3.5, pluggy-1.6.0 -- /home/XXXXXXXXX/anaconda3/envs/metocean-api/bin/python3.13 cachedir: .pytest_cache rootdir: /mnt/c/XXXXXXXXX/Documents/GIT/metocean-api configfile: pyproject.toml plugins: cov-6.1.1 collecting ... collected 17 items tests/test_combine_data.py::test_combine_data PASSED [ 5%] tests/test_extract_data.py::test_extract_nora3_wind PASSED [ 11%] tests/test_extract_data.py::test_download_of_temporary_files PASSED [ 17%] tests/test_extract_data.py::test_extract_nora3_wave PASSED [ 23%] tests/test_extract_data.py::test_nora3_wind_wave_combined PASSED [ 29%] tests/test_extract_data.py::test_extract_nora3_fp PASSED [ 35%] tests/test_extract_data.py::test_extract_nora3_ PASSED [ 41%] tests/test_extract_data.py::test_extract_nora3_atm PASSED [ 47%] tests/test_extract_data.py::test_extract_nora3_atm3hr PASSED [ 52%] tests/test_extract_data.py::test_extract_obs PASSED [ 58%] tests/test_extract_data.py::test_norkyst_800 PASSED [ 64%] tests/test_extract_data.py::test_norkyst_da_zdepth PASSED [ 70%] tests/test_extract_data.py::test_norkyst_da_surface PASSED [ 76%] tests/test_extract_data.py::test_echowave PASSED [ 82%] tests/test_extract_data.py::test_extract_nora3_wave_spectra PASSED [ 88%] tests/test_extract_data.py::test_extract_norac_wave_spectra PASSED [ 94%] tests/test_extract_data.py::test_url_by_date PASSED [100%] =============================== warnings summary =============================== tests/test_extract_data.py::test_extract_nora3_wind :488: RuntimeWarning: numpy.ndarray size changed, may indicate binary incompatibility. Expected 16 from C header, got 96 from PyObject -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html ======================== 17 passed, 1 warning in 50.33s ======================== ============================= test session starts ============================== platform linux -- Python 3.13.3, pytest-8.3.5, pluggy-1.6.0 -- /home/XXXXXXXXX/anaconda3/envs/metocean-api/bin/python3.13 cachedir: .pytest_cache rootdir: /mnt/c/XXXXXXXXX/Documents/GIT/metocean-api configfile: pyproject.toml plugins: cov-6.1.1 collecting ... collected 17 items tests/test_combine_data.py::test_combine_data PASSED [ 5%] tests/test_extract_data.py::test_extract_nora3_wind PASSED [ 11%] tests/test_extract_data.py::test_download_of_temporary_files PASSED [ 17%] tests/test_extract_data.py::test_extract_nora3_wave PASSED [ 23%] tests/test_extract_data.py::test_nora3_wind_wave_combined PASSED [ 29%] tests/test_extract_data.py::test_extract_nora3_fp PASSED [ 35%] tests/test_extract_data.py::test_extract_nora3_ FAILED [ 41%] tests/test_extract_data.py::test_extract_nora3_atm PASSED [ 47%] tests/test_extract_data.py::test_extract_nora3_atm3hr PASSED [ 52%] tests/test_extract_data.py::test_extract_obs PASSED [ 58%] tests/test_extract_data.py::test_norkyst_800 PASSED [ 64%] tests/test_extract_data.py::test_norkyst_da_zdepth PASSED [ 70%] tests/test_extract_data.py::test_norkyst_da_surface PASSED [ 76%] tests/test_extract_data.py::test_echowave PASSED [ 82%] tests/test_extract_data.py::test_extract_nora3_wave_spectra PASSED [ 88%] tests/test_extract_data.py::test_extract_norac_wave_spectra PASSED [ 94%] tests/test_extract_data.py::test_url_by_date PASSED [100%] =================================== FAILURES =================================== _____________________________ test_extract_nora3_ ______________________________ cls = func = . at 0x7f4ce72ecd60> when = 'call' reraise = (, ) @classmethod def from_call( cls, func: Callable[[], TResult], when: Literal["collect", "setup", "call", "teardown"], reraise: type[BaseException] | tuple[type[BaseException], ...] | None = None, ) -> CallInfo[TResult]: """Call func, wrapping the result in a CallInfo. :param func: The function to call. Called without arguments. :type func: Callable[[], _pytest.runner.TResult] :param when: The phase in which the function is called. :param reraise: Exception or exceptions that shall propagate if raised by the function, instead of being wrapped in the CallInfo. """ excinfo = None start = timing.time() precise_start = timing.perf_counter() try: > result: TResult | None = func() /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/runner.py:341: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise ) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/runner.py:242: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = kwargs = {'item': }, firstresult = False def __call__(self, **kwargs: object) -> Any: """Call the hook. Only accepts keyword arguments, which should match the hook specification. Returns the result(s) of calling all registered plugins, see :ref:`calling`. """ assert not self.is_historic(), ( "Cannot directly call a historic hook - use call_historic instead." ) self._verify_all_args_are_provided(kwargs) firstresult = self.spec.opts.get("firstresult", False) if self.spec else False # Copy because plugins may register other plugins during iteration (#438). > return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_hooks.py:512: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.config.PytestPluginManager object at 0x7f4d61013b60> hook_name = 'pytest_runtest_call' methods = [>] kwargs = {'item': }, firstresult = False def _hookexec( self, hook_name: str, methods: Sequence[HookImpl], kwargs: Mapping[str, object], firstresult: bool, ) -> object | list[object]: # called from all hookcaller instances. # enable_tracing will set its own wrapping function at self._inner_hookexec > return self._inner_hookexec(hook_name, methods, kwargs, firstresult) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_manager.py:120: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_name = 'pytest_runtest_call' hook_impls = [>] caller_kwargs = {'item': }, firstresult = False def _multicall( hook_name: str, hook_impls: Sequence[HookImpl], caller_kwargs: Mapping[str, object], firstresult: bool, ) -> object | list[object]: """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from HookCaller.__call__(). """ __tracebackhide__ = True results: list[object] = [] exception = None try: # run impl and wrapper setup functions in a loop teardowns: list[Teardown] = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError as e: # coverage bug - this is tested for argname in hook_impl.argnames: # pragma: no cover if argname not in caller_kwargs: raise HookCallError( f"hook call must provide argument {argname!r}" ) from e if hook_impl.hookwrapper: function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args) next(function_gen) # first yield teardowns.append(function_gen) elif hook_impl.wrapper: try: # If this cast is not valid, a type error is raised below, # which is the desired response. res = hook_impl.function(*args) function_gen = cast(Generator[None, object, object], res) next(function_gen) # first yield teardowns.append(function_gen) except StopIteration: _raise_wrapfail(function_gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException as exc: exception = exc finally: if firstresult: # first result hooks return a single value result = results[0] if results else None else: result = results # run all wrapper post-yield blocks for teardown in reversed(teardowns): try: if exception is not None: try: teardown.throw(exception) except RuntimeError as re: # StopIteration from generator causes RuntimeError # even for coroutine usage - see #544 if ( isinstance(exception, StopIteration) and re.__cause__ is exception ): teardown.close() continue else: raise else: teardown.send(result) # Following is unreachable for a well behaved hook wrapper. # Try to force finalizers otherwise postponed till GC action. # Note: close() may raise if generator handles GeneratorExit. teardown.close() except StopIteration as si: result = si.value exception = None continue except BaseException as e: exception = e continue _raise_wrapfail(teardown, "has second yield") if exception is not None: > raise exception /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_callers.py:167: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_name = 'pytest_runtest_call' hook_impls = [>] caller_kwargs = {'item': }, firstresult = False def _multicall( hook_name: str, hook_impls: Sequence[HookImpl], caller_kwargs: Mapping[str, object], firstresult: bool, ) -> object | list[object]: """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from HookCaller.__call__(). """ __tracebackhide__ = True results: list[object] = [] exception = None try: # run impl and wrapper setup functions in a loop teardowns: list[Teardown] = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError as e: # coverage bug - this is tested for argname in hook_impl.argnames: # pragma: no cover if argname not in caller_kwargs: raise HookCallError( f"hook call must provide argument {argname!r}" ) from e if hook_impl.hookwrapper: function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args) next(function_gen) # first yield teardowns.append(function_gen) elif hook_impl.wrapper: try: # If this cast is not valid, a type error is raised below, # which is the desired response. res = hook_impl.function(*args) function_gen = cast(Generator[None, object, object], res) next(function_gen) # first yield teardowns.append(function_gen) except StopIteration: _raise_wrapfail(function_gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException as exc: exception = exc finally: if firstresult: # first result hooks return a single value result = results[0] if results else None else: result = results # run all wrapper post-yield blocks for teardown in reversed(teardowns): try: if exception is not None: try: > teardown.throw(exception) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_callers.py:139: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ @pytest.hookimpl(wrapper=True, tryfirst=True) def pytest_runtest_call() -> Generator[None]: > yield from thread_exception_runtest_hook() /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/threadexception.py:92: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def thread_exception_runtest_hook() -> Generator[None]: with catch_threading_exception() as cm: try: > yield /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/threadexception.py:68: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_name = 'pytest_runtest_call' hook_impls = [>] caller_kwargs = {'item': }, firstresult = False def _multicall( hook_name: str, hook_impls: Sequence[HookImpl], caller_kwargs: Mapping[str, object], firstresult: bool, ) -> object | list[object]: """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from HookCaller.__call__(). """ __tracebackhide__ = True results: list[object] = [] exception = None try: # run impl and wrapper setup functions in a loop teardowns: list[Teardown] = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError as e: # coverage bug - this is tested for argname in hook_impl.argnames: # pragma: no cover if argname not in caller_kwargs: raise HookCallError( f"hook call must provide argument {argname!r}" ) from e if hook_impl.hookwrapper: function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args) next(function_gen) # first yield teardowns.append(function_gen) elif hook_impl.wrapper: try: # If this cast is not valid, a type error is raised below, # which is the desired response. res = hook_impl.function(*args) function_gen = cast(Generator[None, object, object], res) next(function_gen) # first yield teardowns.append(function_gen) except StopIteration: _raise_wrapfail(function_gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException as exc: exception = exc finally: if firstresult: # first result hooks return a single value result = results[0] if results else None else: result = results # run all wrapper post-yield blocks for teardown in reversed(teardowns): try: if exception is not None: try: > teardown.throw(exception) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_callers.py:139: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ @pytest.hookimpl(wrapper=True, tryfirst=True) def pytest_runtest_call() -> Generator[None]: > yield from unraisable_exception_runtest_hook() /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/unraisableexception.py:95: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def unraisable_exception_runtest_hook() -> Generator[None]: with catch_unraisable_exception() as cm: try: > yield /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/unraisableexception.py:70: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_name = 'pytest_runtest_call' hook_impls = [>] caller_kwargs = {'item': }, firstresult = False def _multicall( hook_name: str, hook_impls: Sequence[HookImpl], caller_kwargs: Mapping[str, object], firstresult: bool, ) -> object | list[object]: """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from HookCaller.__call__(). """ __tracebackhide__ = True results: list[object] = [] exception = None try: # run impl and wrapper setup functions in a loop teardowns: list[Teardown] = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError as e: # coverage bug - this is tested for argname in hook_impl.argnames: # pragma: no cover if argname not in caller_kwargs: raise HookCallError( f"hook call must provide argument {argname!r}" ) from e if hook_impl.hookwrapper: function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args) next(function_gen) # first yield teardowns.append(function_gen) elif hook_impl.wrapper: try: # If this cast is not valid, a type error is raised below, # which is the desired response. res = hook_impl.function(*args) function_gen = cast(Generator[None, object, object], res) next(function_gen) # first yield teardowns.append(function_gen) except StopIteration: _raise_wrapfail(function_gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException as exc: exception = exc finally: if firstresult: # first result hooks return a single value result = results[0] if results else None else: result = results # run all wrapper post-yield blocks for teardown in reversed(teardowns): try: if exception is not None: try: > teardown.throw(exception) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_callers.py:139: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.logging.LoggingPlugin object at 0x7f4d60136900> item = @hookimpl(wrapper=True) def pytest_runtest_call(self, item: nodes.Item) -> Generator[None]: self.log_cli_handler.set_when("call") > yield from self._runtest_for(item, "call") /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/logging.py:846: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.logging.LoggingPlugin object at 0x7f4d60136900> item = , when = 'call' def _runtest_for(self, item: nodes.Item, when: str) -> Generator[None]: """Implement the internals of the pytest_runtest_xxx() hooks.""" with catching_logs( self.caplog_handler, level=self.log_level, ) as caplog_handler, catching_logs( self.report_handler, level=self.log_level, ) as report_handler: caplog_handler.reset() report_handler.reset() item.stash[caplog_records_key][when] = caplog_handler.records item.stash[caplog_handler_key] = caplog_handler try: > yield /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/logging.py:829: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_name = 'pytest_runtest_call' hook_impls = [>] caller_kwargs = {'item': }, firstresult = False def _multicall( hook_name: str, hook_impls: Sequence[HookImpl], caller_kwargs: Mapping[str, object], firstresult: bool, ) -> object | list[object]: """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from HookCaller.__call__(). """ __tracebackhide__ = True results: list[object] = [] exception = None try: # run impl and wrapper setup functions in a loop teardowns: list[Teardown] = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError as e: # coverage bug - this is tested for argname in hook_impl.argnames: # pragma: no cover if argname not in caller_kwargs: raise HookCallError( f"hook call must provide argument {argname!r}" ) from e if hook_impl.hookwrapper: function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args) next(function_gen) # first yield teardowns.append(function_gen) elif hook_impl.wrapper: try: # If this cast is not valid, a type error is raised below, # which is the desired response. res = hook_impl.function(*args) function_gen = cast(Generator[None, object, object], res) next(function_gen) # first yield teardowns.append(function_gen) except StopIteration: _raise_wrapfail(function_gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException as exc: exception = exc finally: if firstresult: # first result hooks return a single value result = results[0] if results else None else: result = results # run all wrapper post-yield blocks for teardown in reversed(teardowns): try: if exception is not None: try: > teardown.throw(exception) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_callers.py:139: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = > _state='suspended' _in_suspended=False> _capture_fixture=None> item = @hookimpl(wrapper=True) def pytest_runtest_call(self, item: Item) -> Generator[None]: with self.item_capture("call", item): > return (yield) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/capture.py:898: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_name = 'pytest_runtest_call' hook_impls = [>] caller_kwargs = {'item': }, firstresult = False def _multicall( hook_name: str, hook_impls: Sequence[HookImpl], caller_kwargs: Mapping[str, object], firstresult: bool, ) -> object | list[object]: """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from HookCaller.__call__(). """ __tracebackhide__ = True results: list[object] = [] exception = None try: # run impl and wrapper setup functions in a loop teardowns: list[Teardown] = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError as e: # coverage bug - this is tested for argname in hook_impl.argnames: # pragma: no cover if argname not in caller_kwargs: raise HookCallError( f"hook call must provide argument {argname!r}" ) from e if hook_impl.hookwrapper: function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args) next(function_gen) # first yield teardowns.append(function_gen) elif hook_impl.wrapper: try: # If this cast is not valid, a type error is raised below, # which is the desired response. res = hook_impl.function(*args) function_gen = cast(Generator[None, object, object], res) next(function_gen) # first yield teardowns.append(function_gen) except StopIteration: _raise_wrapfail(function_gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException as exc: exception = exc finally: if firstresult: # first result hooks return a single value result = results[0] if results else None else: result = results # run all wrapper post-yield blocks for teardown in reversed(teardowns): try: if exception is not None: try: > teardown.throw(exception) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_callers.py:139: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ item = @hookimpl(wrapper=True) def pytest_runtest_call(item: Item) -> Generator[None]: xfailed = item.stash.get(xfailed_key, None) if xfailed is None: item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item) if xfailed and not item.config.option.runxfail and not xfailed.run: xfail("[NOTRUN] " + xfailed.reason) try: > return (yield) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/skipping.py:257: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_name = 'pytest_runtest_call' hook_impls = [>] caller_kwargs = {'item': }, firstresult = False def _multicall( hook_name: str, hook_impls: Sequence[HookImpl], caller_kwargs: Mapping[str, object], firstresult: bool, ) -> object | list[object]: """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from HookCaller.__call__(). """ __tracebackhide__ = True results: list[object] = [] exception = None try: # run impl and wrapper setup functions in a loop teardowns: list[Teardown] = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError as e: # coverage bug - this is tested for argname in hook_impl.argnames: # pragma: no cover if argname not in caller_kwargs: raise HookCallError( f"hook call must provide argument {argname!r}" ) from e if hook_impl.hookwrapper: function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args) next(function_gen) # first yield teardowns.append(function_gen) elif hook_impl.wrapper: try: # If this cast is not valid, a type error is raised below, # which is the desired response. res = hook_impl.function(*args) function_gen = cast(Generator[None, object, object], res) next(function_gen) # first yield teardowns.append(function_gen) except StopIteration: _raise_wrapfail(function_gen, "did not yield") else: > res = hook_impl.function(*args) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_callers.py:121: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ item = def pytest_runtest_call(item: Item) -> None: _update_current_test_var(item, "call") try: del sys.last_type del sys.last_value del sys.last_traceback if sys.version_info >= (3, 12, 0): del sys.last_exc # type:ignore[attr-defined] except AttributeError: pass try: > item.runtest() /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/runner.py:174: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = def runtest(self) -> None: """Execute the underlying test function.""" > self.ihook.pytest_pyfunc_call(pyfuncitem=self) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/python.py:1627: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = kwargs = {'pyfuncitem': }, firstresult = True def __call__(self, **kwargs: object) -> Any: """Call the hook. Only accepts keyword arguments, which should match the hook specification. Returns the result(s) of calling all registered plugins, see :ref:`calling`. """ assert not self.is_historic(), ( "Cannot directly call a historic hook - use call_historic instead." ) self._verify_all_args_are_provided(kwargs) firstresult = self.spec.opts.get("firstresult", False) if self.spec else False # Copy because plugins may register other plugins during iteration (#438). > return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_hooks.py:512: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <_pytest.config.PytestPluginManager object at 0x7f4d61013b60> hook_name = 'pytest_pyfunc_call' methods = [>] kwargs = {'pyfuncitem': }, firstresult = True def _hookexec( self, hook_name: str, methods: Sequence[HookImpl], kwargs: Mapping[str, object], firstresult: bool, ) -> object | list[object]: # called from all hookcaller instances. # enable_tracing will set its own wrapping function at self._inner_hookexec > return self._inner_hookexec(hook_name, methods, kwargs, firstresult) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_manager.py:120: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_name = 'pytest_pyfunc_call' hook_impls = [>] caller_kwargs = {'pyfuncitem': } firstresult = True def _multicall( hook_name: str, hook_impls: Sequence[HookImpl], caller_kwargs: Mapping[str, object], firstresult: bool, ) -> object | list[object]: """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from HookCaller.__call__(). """ __tracebackhide__ = True results: list[object] = [] exception = None try: # run impl and wrapper setup functions in a loop teardowns: list[Teardown] = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError as e: # coverage bug - this is tested for argname in hook_impl.argnames: # pragma: no cover if argname not in caller_kwargs: raise HookCallError( f"hook call must provide argument {argname!r}" ) from e if hook_impl.hookwrapper: function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args) next(function_gen) # first yield teardowns.append(function_gen) elif hook_impl.wrapper: try: # If this cast is not valid, a type error is raised below, # which is the desired response. res = hook_impl.function(*args) function_gen = cast(Generator[None, object, object], res) next(function_gen) # first yield teardowns.append(function_gen) except StopIteration: _raise_wrapfail(function_gen, "did not yield") else: res = hook_impl.function(*args) if res is not None: results.append(res) if firstresult: # halt further impl calls break except BaseException as exc: exception = exc finally: if firstresult: # first result hooks return a single value result = results[0] if results else None else: result = results # run all wrapper post-yield blocks for teardown in reversed(teardowns): try: if exception is not None: try: teardown.throw(exception) except RuntimeError as re: # StopIteration from generator causes RuntimeError # even for coroutine usage - see #544 if ( isinstance(exception, StopIteration) and re.__cause__ is exception ): teardown.close() continue else: raise else: teardown.send(result) # Following is unreachable for a well behaved hook wrapper. # Try to force finalizers otherwise postponed till GC action. # Note: close() may raise if generator handles GeneratorExit. teardown.close() except StopIteration as si: result = si.value exception = None continue except BaseException as e: exception = e continue _raise_wrapfail(teardown, "has second yield") if exception is not None: > raise exception /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_callers.py:167: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ hook_name = 'pytest_pyfunc_call' hook_impls = [>] caller_kwargs = {'pyfuncitem': } firstresult = True def _multicall( hook_name: str, hook_impls: Sequence[HookImpl], caller_kwargs: Mapping[str, object], firstresult: bool, ) -> object | list[object]: """Execute a call into multiple python functions/methods and return the result(s). ``caller_kwargs`` comes from HookCaller.__call__(). """ __tracebackhide__ = True results: list[object] = [] exception = None try: # run impl and wrapper setup functions in a loop teardowns: list[Teardown] = [] try: for hook_impl in reversed(hook_impls): try: args = [caller_kwargs[argname] for argname in hook_impl.argnames] except KeyError as e: # coverage bug - this is tested for argname in hook_impl.argnames: # pragma: no cover if argname not in caller_kwargs: raise HookCallError( f"hook call must provide argument {argname!r}" ) from e if hook_impl.hookwrapper: function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args) next(function_gen) # first yield teardowns.append(function_gen) elif hook_impl.wrapper: try: # If this cast is not valid, a type error is raised below, # which is the desired response. res = hook_impl.function(*args) function_gen = cast(Generator[None, object, object], res) next(function_gen) # first yield teardowns.append(function_gen) except StopIteration: _raise_wrapfail(function_gen, "did not yield") else: > res = hook_impl.function(*args) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/pluggy/_callers.py:121: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ pyfuncitem = @hookimpl(trylast=True) def pytest_pyfunc_call(pyfuncitem: Function) -> object | None: testfunction = pyfuncitem.obj if is_async_function(testfunction): async_warn_and_skip(pyfuncitem.nodeid) funcargs = pyfuncitem.funcargs testargs = {arg: funcargs[arg] for arg in pyfuncitem._fixtureinfo.argnames} > result = testfunction(**testargs) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/python.py:159: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ def test_extract_nora3_(): df_ts = ts.TimeSeries(lon=1.320, lat=53.324,start_time='2000-01-01', end_time='2000-01-02', product='NORA3_') # Import data from thredds.met.no > df_ts.import_data(save_csv=SAVE_CSV,save_nc=SAVE_NC, use_cache=USE_CACHE) tests/test_extract_data.py:94: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = save_csv = True, save_nc = True, use_cache = True def import_data(self, save_csv=True, save_nc=False, use_cache=False): product = products.find_product(self.product) > self.data = product.import_data(self, save_csv, save_nc, use_cache) metocean_api/ts/ts_mod.py:68: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = ts = save_csv = True, save_nc = True, use_cache = True, max_retries = 5 def import_data(self, ts: TimeSeries, save_csv=True, save_nc=False, use_cache=False, max_retries = 5): retry_count = 0 while retry_count < max_retries: try: if retry_count > 0: tempfiles, lon_near, lat_near = self.download_temporary_files(ts, use_cache=True) else: tempfiles, lon_near, lat_near = self.download_temporary_files(ts, use_cache) > return self._combine_temporary_files(ts, save_csv, save_nc, use_cache, tempfiles, lon_near, lat_near, height=ts.height, depth=ts.depth) metocean_api/ts/internal/metno/met_product.py:55: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = ts = save_csv = True, save_nc = True, use_cache = True tempfiles = ['cache/NORA3__lon1.32lat53.324_199912312100.nc', 'cache/NORA3__lon1.32lat53.324_200001010000.nc', 'cache/NORA3__lon1....00001010600.nc', 'cache/NORA3__lon1.32lat53.324_200001010900.nc', 'cache/NORA3__lon1.32lat53.324_200001011200.nc', ...] lon_near = np.float64(1.3199893172215793) lat_near = np.float64(53.32374838481946) flatten_dims = {'depth': None, 'height': None} ds = Size: 26kB Dimensions: (time: 6, hybrid: 65) Coordinates: long... DODS_EXTRA.Unlimited_Dimension: time url: https://thredds.met.no/thredds/dodsC/nor... df = p0 ... y_wind_ml_0.998519629240036m time ... ... 6.44 2000-01-02 00:00:00 101325.0 ... 9.39 [6 rows x 596 columns] def _combine_temporary_files( self, ts: TimeSeries, save_csv, save_nc, use_cache, tempfiles, lon_near, lat_near, **flatten_dims ): print('Merging temporary files...') remove_if_datafile_exists(ts.datafile) # merge temp files > with xr.open_mfdataset(tempfiles, parallel=True, engine="netcdf4") as ds, ProgressBar(): metocean_api/ts/internal/metno/met_product.py:136: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Size: 26kB Dimensions: (time: 6, hybrid: 65) Coordinates: long... DODS_EXTRA.Unlimited_Dimension: time url: https://thredds.met.no/thredds/dodsC/nor... exc_type = None, exc_value = None, traceback = None def __exit__(self, exc_type, exc_value, traceback) -> None: > self.close() /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/xarray/core/common.py:1497: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = Size: 26kB Dimensions: (time: 6, hybrid: 65) Coordinates: long... DODS_EXTRA.Unlimited_Dimension: time url: https://thredds.met.no/thredds/dodsC/nor... def close(self) -> None: """Release any resources linked to this object.""" if self._close is not None: > self._close() /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/xarray/core/common.py:1280: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ closers = [>, >, >, ...] def _multi_file_closer(closers): for closer in closers: > closer() /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/xarray/backends/api.py:284: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = kwargs = {} def close(self, **kwargs): > self._manager.close(**kwargs) /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/xarray/backends/netCDF4_.py:597: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = CachingFileManager(, '/mnt/c/XXXXXXXXX/Documents/GIT/metocean-a...r': True, 'diskless': False, 'persist': False, 'format': 'NETCDF4'}, manager_id='75370149-cb4c-429e-9c7c-8aba04604f50') needs_lock = True def close(self, needs_lock=True): """Explicitly close any associated file object (if necessary).""" # TODO: remove needs_lock if/when we have a reentrant lock in # dask.distributed: https://github.com/dask/dask/issues/3832 with self._optional_lock(needs_lock): default = None file = self._cache.pop(self._key, default) if file is not None: > file.close() /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/xarray/backends/file_manager.py:234: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > ??? src/netCDF4/_netCDF4.pyx:2669: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > ??? src/netCDF4/_netCDF4.pyx:2636: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ > ??? E RuntimeError: NetCDF: Not a valid ID src/netCDF4/_netCDF4.pyx:2164: RuntimeError ----------------------------- Captured stdout call ----------------------------- Nearest point to lat.=53.324,lon.=1.320 was found at lat.=53.324,lon.=1.320 Found cached file cache/NORA3__lon1.32lat53.324_199912312100.nc. Using this instead Found cached file cache/NORA3__lon1.32lat53.324_200001010000.nc. Using this instead Found cached file cache/NORA3__lon1.32lat53.324_200001010300.nc. Using this instead Found cached file cache/NORA3__lon1.32lat53.324_200001010600.nc. Using this instead Found cached file cache/NORA3__lon1.32lat53.324_200001010900.nc. Using this instead Found cached file cache/NORA3__lon1.32lat53.324_200001011200.nc. Using this instead Found cached file cache/NORA3__lon1.32lat53.324_200001011500.nc. Using this instead Found cached file cache/NORA3__lon1.32lat53.324_200001011800.nc. Using this instead Found cached file cache/NORA3__lon1.32lat53.324_200001012100.nc. Using this instead Merging temporary files... [ ] | 0% Completed | 267.24 us [################### ] | 48% Completed | 103.58 ms [###################################### ] | 96% Completed | 203.90 ms [########################################] | 100% Completed | 304.71 ms NetCDF file created at NORA3__lon1.32_lat53.324_20000101_20000102.nc CSV file created at NORA3__lon1.32_lat53.324_20000101_20000102.csv An error occurred: NetCDF: Not a valid ID ----------------------------- Captured stderr call ----------------------------- 0%| | 0/9 [00:00:488: RuntimeWarning: numpy.ndarray size changed, may indicate binary incompatibility. Expected 16 from C header, got 96 from PyObject tests/test_extract_data.py::test_extract_norac_wave_spectra /home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/_pytest/unraisableexception.py:85: PytestUnraisableExceptionWarning: Exception ignored in: Traceback (most recent call last): File "/home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/xarray/backends/file_manager.py", line 250, in __del__ self.close(needs_lock=False) ~~~~~~~~~~^^^^^^^^^^^^^^^^^^ File "/home/XXXXXXXXX/anaconda3/envs/metocean-api/lib/python3.13/site-packages/xarray/backends/file_manager.py", line 234, in close file.close() ~~~~~~~~~~^^ File "src/netCDF4/_netCDF4.pyx", line 2669, in netCDF4._netCDF4.Dataset.close File "src/netCDF4/_netCDF4.pyx", line 2636, in netCDF4._netCDF4.Dataset._close File "src/netCDF4/_netCDF4.pyx", line 2164, in netCDF4._netCDF4._ensure_nc_success RuntimeError: NetCDF: Not a valid ID warnings.warn(pytest.PytestUnraisableExceptionWarning(msg)) -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html =========================== short test summary info ============================ FAILED tests/test_extract_data.py::test_extract_nora3_ - RuntimeError: NetCDF... ================== 1 failed, 16 passed, 2 warnings in 48.85s =================== ============================= test session starts ============================== platform linux -- Python 3.13.3, pytest-8.3.5, pluggy-1.6.0 -- /home/XXXXXXXXX/anaconda3/envs/metocean-api/bin/python3.13 cachedir: .pytest_cache rootdir: /mnt/c/XXXXXXXXX/Documents/GIT/metocean-api configfile: pyproject.toml plugins: cov-6.1.1 collecting ... collected 17 items tests/test_combine_data.py::test_combine_data PASSED [ 5%] tests/test_extract_data.py::test_extract_nora3_wind PASSED [ 11%] tests/test_extract_data.py::test_download_of_temporary_files PASSED [ 17%] tests/test_extract_data.py::test_extract_nora3_wave PASSED [ 23%] tests/test_extract_data.py::test_nora3_wind_wave_combined PASSED [ 29%] tests/test_extract_data.py::test_extract_nora3_fp PASSED [ 35%] tests/test_extract_data.py::test_extract_nora3_ PASSED [ 41%] tests/test_extract_data.py::test_extract_nora3_atm PASSED [ 47%] tests/test_extract_data.py::test_extract_nora3_atm3hr PASSED [ 52%] tests/test_extract_data.py::test_extract_obs PASSED [ 58%] tests/test_extract_data.py::test_norkyst_800 PASSED [ 64%] tests/test_extract_data.py::test_norkyst_da_zdepth PASSED [ 70%] tests/test_extract_data.py::test_norkyst_da_surface PASSED [ 76%] tests/test_extract_data.py::test_echowave PASSED [ 82%] tests/test_extract_data.py::test_extract_nora3_wave_spectra PASSED [ 88%] tests/test_extract_data.py::test_extract_norac_wave_spectra PASSED [ 94%] tests/test_extract_data.py::test_url_by_date PASSED [100%] =============================== warnings summary =============================== tests/test_extract_data.py::test_extract_nora3_wind :488: RuntimeWarning: numpy.ndarray size changed, may indicate binary incompatibility. Expected 16 from C header, got 96 from PyObject -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html ======================== 17 passed, 1 warning in 54.92s ========================