Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
77 changes: 53 additions & 24 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,60 @@
*.tmp
*.autosave
*.bak
*~
*.py[cod]
*.so
*.cfg
!.isort.cfg
!setup.cfg
*.orig
*.log
*.pot
__pycache__/*
.cache/*
.*.swp
*/.ipynb_checkpoints/*
.DS_Store

# These are directories used by IDEs for storing settings
.idea/
.vscode/

# These are common Python virtual enviornment directory names
venv/
docs/venv/

# This is where Jupyter/IPython store backup files
.ipynb_checkpoints/

# Byte-compiled Python
__pycache__/

# These are common build directory names
build*/
docs/build
docs/source/_build
docs/doxyoutput
docs/source/api
*-build-*/
_build/
Debug/
Release/
.ropeproject
.project
.pydevproject
.settings
.idea
.vscode
tags

# Package files
*.egg
*.eggs/
.installed.cfg
*.egg-info

# Unittest and coverage
htmlcov/*
.coverage
.coverage.*
.tox
junit*.xml
coverage.xml
.pytest_cache/

# Build and docs folder/files
build/*
dist/*
sdist/*
docs/source/api/*
!docs/source/api/modules.rst
docs/source/_rst/*
docs/build/*
cover/*
MANIFEST

# Per-project virtualenvs
*venv*/
.conda*/
.python-version

# Users commonly store their specific CMake settings in a toolchain file
toolchain.cmake
Expand All @@ -50,4 +79,4 @@ cache.db
uuid.db

# This is a generated file
src/python/friendzone/friends.py
# src/python/friendzone/friends.py
2 changes: 1 addition & 1 deletion .licenserc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ header:
- docs/source/bibliography/*.bib
- docs/source/nitpick_exceptions
- version.txt
- cmake/friends.py.in
- build/
- venv/

comment: never
16 changes: 0 additions & 16 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,9 @@ include(get_cmaize)
include(nwx_cxx_api_docs)

### Files and Paths ###
set(friends_template "${CMAKE_CURRENT_LIST_DIR}/cmake/friends.py.in")
set(python_src_directory "${CMAKE_CURRENT_LIST_DIR}/src/python")

# # Doxygen docs
if("${ONLY_BUILD_DOCS}")
# If we are only building the docs, we need to produce friends.py here
configure_file(
"${friends_template}"
"${python_src_directory}/friendzone/friends.py"
@ONLY
)
endif()
nwx_cxx_api_docs("${CMAKE_CURRENT_SOURCE_DIR}/src" "${CMAKE_CURRENT_SOURCE_DIR}/include")

### Options ###
Expand Down Expand Up @@ -72,13 +63,6 @@ set(
include(ase)
include(nwchem)

## Configure file with enabled friends ##
configure_file(
"${friends_template}" # Input file
"${python_src_directory}/friendzone/friends.py" # Output file
@ONLY # Only replace @ variables
)

#TOOD: Replace cmaize_add_library when it supports Python
add_library(${PROJECT_NAME} INTERFACE)
target_link_libraries(${PROJECT_NAME} INTERFACE simde ase nwchem)
Expand Down
40 changes: 0 additions & 40 deletions cmake/friends.py.in

This file was deleted.

88 changes: 88 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Copyright 2025 NWChemEx-Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This file defines the pip-installable Python package.

[build-system]
requires = ["setuptools>=46.1.0", "setuptools_scm[toml]>=5"]
build-backend = "setuptools.build_meta"

[tool.setuptools_scm]
# For smarter version schemes and other configuration options,
# check out https://github.com/pypa/setuptools_scm
version_scheme = "no-guess-dev"

# To create a pip-installable package that uses CMake in the backend,
# scikit-build-core is used as the build backend, recommended by Pybind11.
#
# scikit-build-core: https://scikit-build-core.readthedocs.io/en/latest/
# Pybind11 scikit-build-core example: https://github.com/pybind/scikit_build_example
# [build-system]
# requires = ["scikit-build-core>=0.11", "pybind11>=3.0"]
# build-backend = "scikit_build_core.build"


[project]
name = "friendzone"
license = "Apache-2.0"
license-files = ["LICENSE"]
description = "Provides SimDE compatible APIs so that NWChemEx can play nicely with its friends."
readme = "README.md"
authors = [{ name = "zachcran", email = "[email protected]" }]
requires-python = ">=3.10"
classifiers = [
"Development Status :: 4 - Beta",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Private :: Do Not Upload",
]
# Dynamic project attributes
#
# Set the project version dynamically according to git tags.
# Git tag version info: https://github.com/pypa/setuptools-scm/blob/fb261332d9b46aa5a258042d85baa5aa7b9f4fa2/README.rst#default-versioning-scheme
dynamic = ["version"]
# NOTE: Invisible dependency for now until Python bindings at SimDE are
# packaged properly and available here
# dependencies = ["simde"]


[tool.setuptools]
# Cannot automatically find the friendzone namespace so we set it here
package-dir = { "" = "src/python" }

# Optional dependencies represent optional features that can be enabled
# during installation
# Example: pip install friendzone[ase]
[project.optional-dependencies]
ase = ["ase"]
nwchem = ["qcengine", "qcelemental", "networkx"]

# Dependency groups are optional dependencies that are not intented to appear
# after packaging, usually used to help with testing or development
# Example: pip install . --group dev
[dependency-groups]
test = ["pytest"]
dev = [{ include-group = "test" }]

[tool.pytest.ini_options]
minversion = "8.0"
addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config"]
xfail_strict = true
log_cli_level = "INFO"
filterwarnings = ["error", "ignore::pytest.PytestCacheWarning"]
testpaths = ["tests"]
43 changes: 43 additions & 0 deletions src/python/friendzone/friends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright 2025 NWChemEx-Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from importlib.util import find_spec


def friends() -> list[str]:
"""Returns a list of potentially supported friends.

:return: A list of names of potentially supported friends.
:rtype: list[str]
"""
friends_list = [
"ase",
"nwchem",
]
return friends_list


def is_friend_enabled(friend: str) -> bool:
"""Wraps the process of determining if a particular friend was enabled.

:param friend: Name of friend to check
:type friend: str

:return: True if FriendZone was configured with support for ``friend``
and false otherwise.
:rtype: bool
"""
if friend in friends() and find_spec(friend) is not None:
return True
return False
34 changes: 34 additions & 0 deletions tests/python/unit_tests/test_friends.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2025 NWChemEx-Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest
from importlib.util import find_spec

from friendzone.friends import friends, is_friend_enabled


class TestFriends(unittest.TestCase):
def test_friends_list(self):
expected_friends = ["ase", "nwchem"]
actual_friends = friends()
self.assertCountEqual(actual_friends, expected_friends)

def test_is_friend_enabled(self):
# For known friends, the result should match the system state
for friend in friends():
enabled = is_friend_enabled(friend)
module_found = find_spec(friend) is not None
self.assertEqual(enabled, module_found)
# For unknown friends, the result should be False
self.assertFalse(is_friend_enabled("non_existent_friend"))