| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
Thank you for your contribution to Astropy! 🌌 This checklist is meant to remind the package maintainers who will review this pull request of some common things to look for.
|
Sorry, something went wrong.
There was a problem hiding this comment.
This looks OK, except that it would seem we are papering over a bug in jplephem: the _kernel attribute should be deleted on shutdown, and presumably it internally would close its resources. I found the maintainer very responsive, so if you've got a sense of what the problem might be, I suggest raising an issue there (and link to it in the comment here).
Sorry, something went wrong.
|
I've contributed to jplephem already. In fact I made it abi3-compliant so it doesn't need a yearly re-release :) |
Sorry, something went wrong.
|
To be clear, astropy is really the one managing jplephem.spk.SPK instances, opening them without a defined closing point. And because this happens through public APIs other than context managers, I don't see any other way but to customize the __del__ to ensure that resources are properly finalized. |
Sorry, something went wrong.
There was a problem hiding this comment.
@neutrinoceros - OK, so the problem is that in _get_kernel() we open the SPK, but we only explicitly close it if we change kernel, and you now add that it gets closed if the science state gets deleted.
That seems reasonable, and I now see in _get_body_barycentric_posvel, we even have an enormous try/except to ensure the SPK gets closed as well.
This then brings up the question if a better solution might be to make _get_kernel a simple class, like,
class _KernelWrapper:
def __init__(self, value):
self.kernel = <content of current file>
def __getattr__(self, attr):
return getattr(self.kernel, attr)
def __del__(self):
<close file>
Or possibly one can just inherit from SPK, like
class _SelfClosingSPK(SPK):
def __new__(cls, value):
return cls.open(value)
def __del__(self):
self.daf.close()
(but that makes me wonder again whether that would not be a welcome contribution to kplephem).
A scheme like the above would also eliminate the try/except, and allow us to just overwrite _kernel in the science state (which is good since in principle someone might still be hanging on to the kernel, and it is not nice that it gets closed on one if one changes state). What do you think?
Sorry, something went wrong.
|
Perhaps even simpler, class SPKAutoCloser(SPK):
def __del__(self):
self.daf.close()
super().__del__()
and then use kernel = SPKAutoCloser.open(value) inside the existing routines. |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Description
I noticed this warning was popping up more frequently in my personal runs of the test suite, and while the test already had some guard rails for it, they are clearly not sufficient (and to some extent, misleading, my bad). Let's try this instead.
For completion, here's the warning:
2026-08-15T08:13:50.3223489Z =================================== FAILURES =================================== 2026-08-15T08:13:50.3224291Z ___________________ test_ephemeris_local_file_not_ephemeris ____________________ 2026-08-15T08:13:50.3225291Z [gw0] linux -- Python 3.14.7 /home/runner/work/astropy-compatibility-checks/astropy-compatibility-checks/all-nightlies/.venv/bin/python 2026-08-15T08:13:50.3226041Z 2026-08-15T08:13:50.3226398Z self = <tempfile._TemporaryFileCloser object at 0x7f20e5a1a3c0> 2026-08-15T08:13:50.3226818Z 2026-08-15T08:13:50.3227044Z def __del__(self): 2026-08-15T08:13:50.3227424Z close_called = self.close_called 2026-08-15T08:13:50.3227841Z self.cleanup() 2026-08-15T08:13:50.3228198Z if not close_called: 2026-08-15T08:13:50.3228646Z > _warnings.warn(self.warn_message, ResourceWarning) 2026-08-15T08:13:50.3229593Z E ResourceWarning: Implicitly cleaning up <HTTPError 404: 'Not Found'> 2026-08-15T08:13:50.3230050Z 2026-08-15T08:13:50.3230533Z ../../../../../_temp/uv-python-dir/cpython-3.14.7-linux-x86_64-gnu/lib/python3.14/tempfile.py:484: ResourceWarning 2026-08-15T08:13:50.3231113Z 2026-08-15T08:13:50.3231446Z The above exception was the direct cause of the following exception: 2026-08-15T08:13:50.3231898Z 2026-08-15T08:13:50.3232143Z cls = <class '_pytest.runner.CallInfo'> 2026-08-15T08:13:50.3232654Z func = <function call_and_report.<locals>.<lambda> at 0x7f20d4f5a560> 2026-08-15T08:13:50.3233182Z when = 'call' 2026-08-15T08:13:50.3233632Z reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>) 2026-08-15T08:13:50.3234076Z 2026-08-15T08:13:50.3234294Z @classmethod 2026-08-15T08:13:50.3234626Z def from_call( 2026-08-15T08:13:50.3234960Z cls, 2026-08-15T08:13:50.3235305Z func: Callable[[], TResult], 2026-08-15T08:13:50.3235762Z when: Literal["collect", "setup", "call", "teardown"], 2026-08-15T08:13:50.3236376Z reraise: type[BaseException] | tuple[type[BaseException], ...] | None = None, 2026-08-15T08:13:50.3236962Z ) -> CallInfo[TResult]: 2026-08-15T08:13:50.3237382Z """Call func, wrapping the result in a CallInfo. 2026-08-15T08:13:50.3237817Z 2026-08-15T08:13:50.3238133Z :param func: 2026-08-15T08:13:50.3238543Z The function to call. Called without arguments. 2026-08-15T08:13:50.3239180Z :type func: Callable[[], _pytest.runner.TResult] 2026-08-15T08:13:50.3239629Z :param when: 2026-08-15T08:13:50.3240017Z The phase in which the function is called. 2026-08-15T08:13:50.3240454Z :param reraise: 2026-08-15T08:13:50.3240923Z Exception or exceptions that shall propagate if raised by the 2026-08-15T08:13:50.3241493Z function, instead of being wrapped in the CallInfo. 2026-08-15T08:13:50.3241953Z """ 2026-08-15T08:13:50.3242276Z excinfo = None 2026-08-15T08:13:50.3242636Z instant = timing.Instant() 2026-08-15T08:13:50.3243011Z try: 2026-08-15T08:13:50.3243361Z > result: TResult | None = func() 2026-08-15T08:13:50.3243780Z ^^^^^^ 2026-08-15T08:13:50.3244087Z 2026-08-15T08:13:50.3244398Z ../../.venv/lib/python3.14/site-packages/_pytest/runner.py:361: 2026-08-15T08:13:50.3244943Z _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 2026-08-15T08:13:50.3245522Z ../../.venv/lib/python3.14/site-packages/_pytest/runner.py:250: in <lambda> 2026-08-15T08:13:50.3246497Z lambda: runtest_hook(item=item, **kwds), 2026-08-15T08:13:50.3246930Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-08-15T08:13:50.3247435Z ../../.venv/lib/python3.14/site-packages/pluggy/_hooks.py:512: in __call__ 2026-08-15T08:13:50.3248101Z return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult) 2026-08-15T08:13:50.3249051Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-08-15T08:13:50.3249658Z ../../.venv/lib/python3.14/site-packages/pluggy/_manager.py:120: in _hookexec 2026-08-15T08:13:50.3250332Z return self._inner_hookexec(hook_name, methods, kwargs, firstresult) 2026-08-15T08:13:50.3250893Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2026-08-15T08:13:50.3251497Z ../../.venv/lib/python3.14/site-packages/_pytest/logging.py:865: in pytest_runtest_call 2026-08-15T08:13:50.3252078Z yield 2026-08-15T08:13:50.3260107Z ../../.venv/lib/python3.14/site-packages/_pytest/capture.py:900: in pytest_runtest_call 2026-08-15T08:13:50.3260956Z return (yield) 2026-08-15T08:13:50.3261304Z ^^^^^ 2026-08-15T08:13:50.3261855Z ../../.venv/lib/python3.14/site-packages/pluggy/_callers.py:53: in run_old_style_hookwrapper 2026-08-15T08:13:50.3262491Z return result.get_result() 2026-08-15T08:13:50.3262887Z ^^^^^^^^^^^^^^^^^^^ 2026-08-15T08:13:50.3263432Z ../../.venv/lib/python3.14/site-packages/pluggy/_callers.py:38: in run_old_style_hookwrapper 2026-08-15T08:13:50.3264110Z res = yield 2026-08-15T08:13:50.3264462Z ^^^^^ 2026-08-15T08:13:50.3264953Z ../../.venv/lib/python3.14/site-packages/_pytest/skipping.py:268: in pytest_runtest_call 2026-08-15T08:13:50.3265528Z return (yield) 2026-08-15T08:13:50.3265862Z ^^^^^ 2026-08-15T08:13:50.3266414Z ../../.venv/lib/python3.14/site-packages/_pytest/unraisableexception.py:183: in pytest_runtest_call 2026-08-15T08:13:50.3267058Z collect_unraisable(item.config) 2026-08-15T08:13:50.3267685Z ../../.venv/lib/python3.14/site-packages/_pytest/unraisableexception.py:79: in collect_unraisable 2026-08-15T08:13:50.3268302Z raise errors[0] 2026-08-15T08:13:50.3268715Z _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 2026-08-15T08:13:50.3269248Z 2026-08-15T08:13:50.3269546Z config = <_pytest.config.Config object at 0x7f211b8b1a90> 2026-08-15T08:13:50.3269936Z 2026-08-15T08:13:50.3270211Z def collect_unraisable(config: Config) -> None: 2026-08-15T08:13:50.3270757Z pop_unraisable = config.stash[unraisable_exceptions].pop 2026-08-15T08:13:50.3271401Z errors: list[pytest.PytestUnraisableExceptionWarning | RuntimeError] = [] 2026-08-15T08:13:50.3271975Z meta = None 2026-08-15T08:13:50.3272327Z hook_error = None 2026-08-15T08:13:50.3272688Z try: 2026-08-15T08:13:50.3273020Z while True: 2026-08-15T08:13:50.3273370Z try: 2026-08-15T08:13:50.3273731Z meta = pop_unraisable() 2026-08-15T08:13:50.3274168Z except IndexError: 2026-08-15T08:13:50.3274561Z break 2026-08-15T08:13:50.3274911Z 2026-08-15T08:13:50.3275334Z if isinstance(meta, BaseException): 2026-08-15T08:13:50.3275900Z hook_error = RuntimeError("Failed to process unraisable exception") 2026-08-15T08:13:50.3276474Z hook_error.__cause__ = meta 2026-08-15T08:13:50.3276924Z errors.append(hook_error) 2026-08-15T08:13:50.3277341Z continue 2026-08-15T08:13:50.3277702Z 2026-08-15T08:13:50.3278022Z msg = meta.msg 2026-08-15T08:13:50.3278387Z try: 2026-08-15T08:13:50.3278978Z > warnings.warn(pytest.PytestUnraisableExceptionWarning(msg)) 2026-08-15T08:13:50.3280022Z E pytest.PytestUnraisableExceptionWarning: Exception ignored while calling deallocator <function _TemporaryFileCloser.__del__ at 0x7f211bcfbcc0>: None 2026-08-15T08:13:50.3281080Z 2026-08-15T08:13:50.3281590Z ../../.venv/lib/python3.14/site-packages/_pytest/unraisableexception.py:67: PytestUnraisableExceptionWarningDisclaimer: the problem I'm attempting to solve here isn't deterministic and supposedly at least somewhat hard to reproduce since we apparently never hit it in regular CI.