Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ORM: Return None in get_function_source_code instead of excepting #5730

Merged
merged 1 commit into from
Oct 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions aiida/orm/utils/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
# For further information please visit http://www.aiida.net #
###########################################################################
"""Mixin classes for ORM classes."""
from __future__ import annotations

import inspect
from typing import List, Optional

Expand Down Expand Up @@ -104,12 +106,19 @@ def _set_function_starting_line_number(self, function_starting_line_number):
"""
self.base.attributes.set(self.FUNCTION_STARTING_LINE_KEY, function_starting_line_number)

def get_function_source_code(self):
"""Return the absolute path to the source file in the repository.
def get_function_source_code(self) -> str | None:
"""Return the source code of the function stored in the repository.

If the source code file does not exist, this will return ``None`` instead. This can happen for example when the
function was defined in an interactive shell in which case ``store_source_info`` will have failed to retrieve
the source code using ``inspect.getsourcefile``.

:returns: the absolute path of the source file in the repository, or None if it does not exist
:returns: The source code of the function or ``None`` if it could not be determined when storing the node.
"""
return self.base.repository.get_object_content(self.FUNCTION_SOURCE_FILE_PATH)
try:
return self.base.repository.get_object_content(self.FUNCTION_SOURCE_FILE_PATH)
except FileNotFoundError:
return None


class Sealable:
Expand Down
17 changes: 17 additions & 0 deletions tests/engine/test_process_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,23 @@ def test_process_function(data):
assert node.function_name in function_name_from_source


@pytest.mark.usefixtures('aiida_profile')
def test_get_function_source_code():
"""Test that ``get_function_source_code`` returns ``None`` if no source code was stored.

This is the case for example for functions defined in an interactive shell, where the retrieval of the source code
upon storing the node fails and nothing is stored. The function should not except in this case.
"""
from aiida.orm.utils.mixins import FunctionCalculationMixin

_, node = function_return_true.run_get_node()

# Delete the source file by going down to the ``RepositoryBackend`` to circumvent the immutability check.
node.base.repository._repository.delete_object(FunctionCalculationMixin.FUNCTION_SOURCE_FILE_PATH) # pylint: disable=protected-access

assert node.get_function_source_code() is None


@pytest.mark.usefixtures('aiida_profile_clean')
def test_function_varargs():
"""Variadic arguments are not supported and should raise."""
Expand Down