Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sf_ip_ea/_static_version.py export-subst
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ install:
- sudo apt-get update
# We do this conditionally because it saves us some downloading if the
# version is the same.
- wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh;
- wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
- bash miniconda.sh -b -p $HOME/miniconda
- export PATH="$HOME/miniconda/bin:$PATH"
- conda config --set always_yes yes --set changeps1 no
Expand Down
29 changes: 29 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
BSD 3-Clause License

Copyright (c) 2019-2021, Shannon E. Houck
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 changes: 37 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,49 @@
from distutils.core import setup
import setuptools


def get_version_and_cmdclass(package_path):
"""Load version.py module without importing the whole package.

Template code from miniver
"""
import os
from importlib.util import module_from_spec, spec_from_file_location

spec = spec_from_file_location("version", os.path.join(package_path, "_version.py"))
module = module_from_spec(spec)
spec.loader.exec_module(module)
return module.__version__, module.cmdclass


version, cmdclass = get_version_and_cmdclass("sf_ip_ea")


setup(
name='sf_ip_ea',
version='0.1.0',
version=version,
cmdclass=cmdclass,
author='Shannon E. Houck',
author_email='shouck@vt.edu',
packages=['sf_ip_ea', 'sf_ip_ea.test'],
packages=setuptools.find_packages(),
include_package_data=True,
scripts=[],
url='',
license='LICENSE.txt',
install_requires=[
"numpy>=1.7",
"scipy",
],
extras_require={
"tests": ["pytest",],
},
tests_require=["pytest",],
classifiers=[
"Development Status :: 4 - Beta",
"Intended Audience :: Science/Research",
"Programming Language :: Python :: 3",
],
zip_safe=False,
description='Stand-alone RAS-SF-IP/EA code.',
long_description=open('README.md').read(),
)
1 change: 1 addition & 0 deletions sf_ip_ea/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,4 @@ def fock_ci(delta_a, delta_b, mol, conf_space="", ref_opts={}, sf_opts={},
print("ERROR: Program %s is not yet supported. Exiting..." %(program) )
exit()

from ._version import __version__
12 changes: 12 additions & 0 deletions sf_ip_ea/_static_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
# This file is part of 'miniver': https://github.com/jbweston/miniver
#
# This file will be overwritten by setup.py when a source or binary
# distribution is made. The magic value "__use_git__" is interpreted by
# version.py.

version = "__use_git__"

# These values are only set if the distribution was created with 'git archive'
refnames = "$Format:%D$"
git_hash = "$Format:%h$"
207 changes: 207 additions & 0 deletions sf_ip_ea/_version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# -*- coding: utf-8 -*-
# This file is part of 'miniver': https://github.com/jbweston/miniver
#
from collections import namedtuple
import os
import subprocess

from setuptools.command.build_py import build_py as build_py_orig
from setuptools.command.sdist import sdist as sdist_orig

Version = namedtuple("Version", ("release", "dev", "labels"))

# No public API
__all__ = []

package_root = os.path.dirname(os.path.realpath(__file__))
package_name = os.path.basename(package_root)
distr_root = os.path.dirname(package_root)
# If the package is inside a "src" directory the
# distribution root is 1 level up.
if os.path.split(distr_root)[1] == "src":
_package_root_inside_src = True
distr_root = os.path.dirname(distr_root)
else:
_package_root_inside_src = False

STATIC_VERSION_FILE = "_static_version.py"


def get_version(version_file=STATIC_VERSION_FILE):
version_info = get_static_version_info(version_file)
version = version_info["version"]
if version == "__use_git__":
version = get_version_from_git()
if not version:
version = get_version_from_git_archive(version_info)
if not version:
version = Version("unknown", None, None)
return pep440_format(version)
else:
return version


def get_static_version_info(version_file=STATIC_VERSION_FILE):
version_info = {}
with open(os.path.join(package_root, version_file), "rb") as f:
exec(f.read(), {}, version_info)
return version_info


def version_is_from_git(version_file=STATIC_VERSION_FILE):
return get_static_version_info(version_file)["version"] == "__use_git__"


def pep440_format(version_info):
release, dev, labels = version_info

version_parts = [release]
if dev:
if release.endswith("-dev") or release.endswith(".dev"):
version_parts.append(dev)
else: # prefer PEP440 over strict adhesion to semver
version_parts.append(".dev{}".format(dev))

if labels:
version_parts.append("+")
version_parts.append(".".join(labels))

return "".join(version_parts)


def get_version_from_git():
try:
p = subprocess.Popen(
["git", "rev-parse", "--show-toplevel"],
cwd=distr_root,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
except OSError:
return
if p.wait() != 0:
return
if not os.path.samefile(p.communicate()[0].decode().rstrip("\n"), distr_root):
# The top-level directory of the current Git repository is not the same
# as the root directory of the distribution: do not extract the
# version from Git.
return

# git describe --first-parent does not take into account tags from branches
# that were merged-in. The '--long' flag gets us the 'dev' version and
# git hash, '--always' returns the git hash even if there are no tags.
for opts in [["--first-parent"], []]:
try:
p = subprocess.Popen(
["git", "describe", "--long", "--always"] + opts,
cwd=distr_root,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
except OSError:
return
if p.wait() == 0:
break
else:
return

description = (
p.communicate()[0]
.decode()
.strip("v") # Tags can have a leading 'v', but the version should not
.rstrip("\n")
.rsplit("-", 2) # Split the latest tag, commits since tag, and hash
)

try:
release, dev, git = description
except ValueError: # No tags, only the git hash
# prepend 'g' to match with format returned by 'git describe'
git = "g{}".format(*description)
release = "unknown"
dev = None

labels = []
if dev == "0":
dev = None
else:
labels.append(git)

try:
p = subprocess.Popen(["git", "diff", "--quiet"], cwd=distr_root)
except OSError:
labels.append("confused") # This should never happen.
else:
if p.wait() == 1:
labels.append("dirty")

return Version(release, dev, labels)


# TODO: change this logic when there is a git pretty-format
# that gives the same output as 'git describe'.
# Currently we can only tell the tag the current commit is
# pointing to, or its hash (with no version info)
# if it is not tagged.
def get_version_from_git_archive(version_info):
try:
refnames = version_info["refnames"]
git_hash = version_info["git_hash"]
except KeyError:
# These fields are not present if we are running from an sdist.
# Execution should never reach here, though
return None

if git_hash.startswith("$Format") or refnames.startswith("$Format"):
# variables not expanded during 'git archive'
return None

VTAG = "tag: v"
refs = set(r.strip() for r in refnames.split(","))
version_tags = set(r[len(VTAG) :] for r in refs if r.startswith(VTAG))
if version_tags:
release, *_ = sorted(version_tags) # prefer e.g. "2.0" over "2.0rc1"
return Version(release, dev=None, labels=None)
else:
return Version("unknown", dev=None, labels=["g{}".format(git_hash)])


__version__ = get_version()


# The following section defines a module global 'cmdclass',
# which can be used from setup.py. The 'package_name' and
# '__version__' module globals are used (but not modified).


def _write_version(fname):
# This could be a hard link, so try to delete it first. Is there any way
# to do this atomically together with opening?
try:
os.remove(fname)
except OSError:
pass
with open(fname, "w") as f:
f.write(
"# This file has been created by setup.py.\n"
"version = '{}'\n".format(__version__)
)


class _build_py(build_py_orig):
def run(self):
super().run()
_write_version(os.path.join(self.build_lib, package_name, STATIC_VERSION_FILE))


class _sdist(sdist_orig):
def make_release_tree(self, base_dir, files):
super().make_release_tree(base_dir, files)
if _package_root_inside_src:
p = os.path.join("src", package_name)
else:
p = package_name
_write_version(os.path.join(base_dir, p, STATIC_VERSION_FILE))


cmdclass = dict(sdist=_sdist, build_py=_build_py)
1 change: 1 addition & 0 deletions sf_ip_ea/test/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

21 changes: 21 additions & 0 deletions sf_ip_ea/test/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pytest


def pytest_configure(config):
# Register marks to avoid warnings in installed testing
# sync with setup.cfg
config.addinivalue_line("markers", "blochtest")
config.addinivalue_line("markers", "davidsontest")
config.addinivalue_line("markers", "dftest")
config.addinivalue_line("markers", "frozentest")
config.addinivalue_line("markers", "methodtest")


@pytest.fixture(scope="function", autouse=True)
def set_up():
import psi4

psi4.core.clean()
# psi4.core.clean_timers() # uncomment when v1.4 is lowest supported
psi4.core.clean_options()
psi4.set_output_file("pytest_output.dat", True)
2 changes: 2 additions & 0 deletions sf_ip_ea/test/pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ markers =
methodtest: test the SF-IP/EA methods for correct energy values
blochtest: test the Bloch effective Hamiltonian build
frozentest: test frozen core/virtual
dftest
davidsontest
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Loading