From 274d0eb5c2e0ba63bd3655c5a2862c6c080f77e8 Mon Sep 17 00:00:00 2001 From: Sparks29032 Date: Wed, 13 Mar 2024 03:26:45 -0400 Subject: [PATCH 1/5] Update for 3.9+ --- examples/distanceprinter.py | 4 +- examples/parallelPDF.py | 4 +- src/diffpy/srreal/_version_data.py | 23 +++++----- src/diffpy/srreal/tests/__init__.py | 47 +++++++++++---------- src/diffpy/srreal/tests/testpairquantity.py | 2 +- src/diffpy/srreal/tests/testutils.py | 4 +- 6 files changed, 43 insertions(+), 41 deletions(-) diff --git a/examples/distanceprinter.py b/examples/distanceprinter.py index 45ae0e65..e39a364d 100755 --- a/examples/distanceprinter.py +++ b/examples/distanceprinter.py @@ -45,8 +45,8 @@ def _addPairContribution(self, bnds, sumscale): distprint._setDoubleAttr('rmax', 10) def get_pyobjcryst_sphalerite(): - from pyobjcryst import loadCrystal - crst = loadCrystal('datafiles/sphalerite.cif') + from pyobjcryst.crystal import create_crystal_from_cif + crst = create_crystal_from_cif('datafiles/sphalerite.cif') return crst def main(): diff --git a/examples/parallelPDF.py b/examples/parallelPDF.py index 9040b28d..f6f0833c 100755 --- a/examples/parallelPDF.py +++ b/examples/parallelPDF.py @@ -30,9 +30,9 @@ # load menthol structure and make sure Uiso values are non-zero if opts.pyobjcryst: # use pyobjcryst if requested by the user - from pyobjcryst import loadCrystal + from pyobjcryst.crystal import create_crystal_crom_cif from numpy import pi - menthol = loadCrystal(mentholcif) + menthol = create_crystal_crom_cif(mentholcif) for sc in menthol.GetScatteringComponentList(): sp = sc.mpScattPow sp.Biso = sp.Biso or 8 * pi**2 * Uisodefault diff --git a/src/diffpy/srreal/_version_data.py b/src/diffpy/srreal/_version_data.py index a0e532b6..42cc0141 100644 --- a/src/diffpy/srreal/_version_data.py +++ b/src/diffpy/srreal/_version_data.py @@ -23,21 +23,22 @@ import os.path -from pkg_resources import resource_filename +from importlib.resources import files, as_file # obtain version information from the version.cfg file cp = dict(version='', date='', commit='', timestamp='0') -fcfg = resource_filename(__name__, 'version.cfg') -if not os.path.isfile(fcfg): # pragma: no cover - from warnings import warn - warn('Package metadata not found, execute "./setup.py egg_info".') - fcfg = os.devnull -with open(fcfg) as fp: - kwords = [[w.strip() for w in line.split(' = ', 1)] - for line in fp if line[:1].isalpha() and ' = ' in line] -assert all(w[0] in cp for w in kwords), "received unrecognized keyword" -cp.update(kwords) +ref = files(__package__) / 'version.cfg' +with as_file(ref) as fcfg: + if not os.path.isfile(fcfg): # pragma: no cover + from warnings import warn + warn('Package metadata not found, execute "./setup.py egg_info".') + fcfg = os.devnull + with open(fcfg) as fp: + kwords = [[w.strip() for w in line.split(' = ', 1)] + for line in fp if line[:1].isalpha() and ' = ' in line] + assert all(w[0] in cp for w in kwords), "received unrecognized keyword" + cp.update(kwords) __version__ = cp['version'] __date__ = cp['date'] diff --git a/src/diffpy/srreal/tests/__init__.py b/src/diffpy/srreal/tests/__init__.py index f1b64d71..13904899 100644 --- a/src/diffpy/srreal/tests/__init__.py +++ b/src/diffpy/srreal/tests/__init__.py @@ -43,30 +43,31 @@ def testsuite(pattern=''): import re from os.path import dirname from itertools import chain - from pkg_resources import resource_filename + from importlib.resources import files, as_file loader = unittest.defaultTestLoader - thisdir = resource_filename(__name__, '') - depth = __name__.count('.') + 1 - topdir = thisdir - for i in range(depth): - topdir = dirname(topdir) - suite_all = loader.discover(thisdir, top_level_dir=topdir) - # always filter the suite by pattern to test-cover the selection code. - suite = unittest.TestSuite() - rx = re.compile(pattern) - tsuites = list(chain.from_iterable(suite_all)) - tsok = all(isinstance(ts, unittest.TestSuite) for ts in tsuites) - if not tsok: # pragma: no cover - return suite_all - tcases = chain.from_iterable(tsuites) - for tc in tcases: - tcwords = tc.id().split('.') - shortname = '.'.join(tcwords[-3:]) - if rx.search(shortname): - suite.addTest(tc) - # verify all tests are found for an empty pattern. - assert pattern or suite_all.countTestCases() == suite.countTestCases() - return suite + ref = files(__package__) + with as_file(ref) as thisdir: + depth = __name__.count('.') + 1 + topdir = thisdir + for i in range(depth): + topdir = dirname(topdir) + suite_all = loader.discover(thisdir, top_level_dir=topdir) + # always filter the suite by pattern to test-cover the selection code. + suite = unittest.TestSuite() + rx = re.compile(pattern) + tsuites = list(chain.from_iterable(suite_all)) + tsok = all(isinstance(ts, unittest.TestSuite) for ts in tsuites) + if not tsok: # pragma: no cover + return suite_all + tcases = chain.from_iterable(tsuites) + for tc in tcases: + tcwords = tc.id().split('.') + shortname = '.'.join(tcwords[-3:]) + if rx.search(shortname): + suite.addTest(tc) + # verify all tests are found for an empty pattern. + assert pattern or suite_all.countTestCases() == suite.countTestCases() + return suite def test(): diff --git a/src/diffpy/srreal/tests/testpairquantity.py b/src/diffpy/srreal/tests/testpairquantity.py index c54c27e9..a0ebffa6 100644 --- a/src/diffpy/srreal/tests/testpairquantity.py +++ b/src/diffpy/srreal/tests/testpairquantity.py @@ -83,7 +83,7 @@ def test_setPairMask_args(self): spm = self.pq.setPairMask gpm = self.pq.getPairMask self.assertRaises(TypeError, spm, 0.0, 0, False) - self.assertRaises(TypeError, spm, numpy.complex(0.5), 0, False) + self.assertRaises(TypeError, spm, numpy.complex128(0.5), 0, False) self.assertTrue(gpm(0, 0)) spm(numpy.int32(1), 0, True, others=False) self.assertTrue(gpm(0, 1)) diff --git a/src/diffpy/srreal/tests/testutils.py b/src/diffpy/srreal/tests/testutils.py index 0cead96d..56854b3d 100644 --- a/src/diffpy/srreal/tests/testutils.py +++ b/src/diffpy/srreal/tests/testutils.py @@ -62,9 +62,9 @@ def datafile(filename): def loadObjCrystCrystal(filename): - from pyobjcryst import loadCrystal + from pyobjcryst.crystal import create_crystal_from_cif fullpath = datafile(filename) - crst = loadCrystal(fullpath) + crst = create_crystal_from_cif(fullpath) return crst From 5cbb9ba531234c6cf44cbcf775a4b702f68cabda Mon Sep 17 00:00:00 2001 From: Sparks29032 Date: Sat, 25 May 2024 19:47:34 -0400 Subject: [PATCH 2/5] Initial pyproject.toml --- pyproject.toml | 56 +++++++++++++++++++++++++ setup.py | 110 ++----------------------------------------------- 2 files changed, 59 insertions(+), 107 deletions(-) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..d52cfb6c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,56 @@ +[build-system] +requires = ["setuptools>=62.0", "setuptools-git-versioning<2", "numpy"] +build-backend = "setuptools.build_meta" + +[project] +name = "diffpy.srreal" +dynamic=['version'] +authors = [ + { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, +] +maintainers = [ + { name="Simon J.L. Billinge group", email="simon.billinge@gmail.com" }, +] +description = "calculators for PDF, bond valence sum, and other quantities based on atom pair interaction." +keywords = ["PDF BVS atom overlap calculator real-space"] +readme = "README.rst" +requires-python = ">=3.9" +dependencies = [ + "diffpy.structure", +] +classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'Intended Audience :: Education', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: BSD License', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: POSIX', + 'Operating System :: Unix', + 'Programming Language :: C++', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', + 'Topic :: Scientific/Engineering :: Chemistry', + 'Topic :: Scientific/Engineering :: Physics', + 'Topic :: Software Development :: Libraries', +] + +[project.urls] +Homepage = "https://github.com/diffpy/diffpy.srreal/" +Issues = "https://github.com/diffpy/diffpy.srreal/issues" + +[tool.setuptools-git-versioning] +enabled = true +template = "{tag}" +dev_template = "{tag}" +dirty_template = "{tag}" + +[tool.setuptools.packages.find] +where = ["src"] # list of folders that contain the packages (["."] by default) +include = ["diffpy*"] # package names should match these glob patterns (["*"] by default) +exclude = ["diffpy.srreal.tests*"] # exclude packages matching these glob patterns (empty by default) +namespaces = false # to disable scanning PEP 420 namespaces (true by default) diff --git a/setup.py b/setup.py index 6256a9f5..556d9ccb 100755 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ import re import sys import glob -from setuptools import setup, find_packages +from setuptools import setup from setuptools import Extension from numpy.distutils.misc_util import get_numpy_include_dirs @@ -78,116 +78,12 @@ def create_extensions(): return [ext] -# versioncfgfile holds version data for git commit hash and date. -# It must reside in the same directory as version.py. -MYDIR = os.path.dirname(os.path.abspath(__file__)) -versioncfgfile = os.path.join(MYDIR, 'src/diffpy/srreal/version.cfg') -gitarchivecfgfile = os.path.join(MYDIR, '.gitarchive.cfg') - - -def gitinfo(): - from subprocess import Popen, PIPE - kw = dict(stdout=PIPE, cwd=MYDIR, universal_newlines=True) - proc = Popen(['git', 'describe', '--match=v[[:digit:]]*'], **kw) - desc = proc.stdout.read() - proc = Popen(['git', 'log', '-1', '--format=%H %ct %ci'], **kw) - glog = proc.stdout.read() - rv = {} - rv['version'] = '.post'.join(desc.strip().split('-')[:2]).lstrip('v') - rv['commit'], rv['timestamp'], rv['date'] = glog.strip().split(None, 2) - return rv - - -def getversioncfg(): - if PY3: - from configparser import RawConfigParser - else: - from ConfigParser import RawConfigParser - vd0 = dict(version=FALLBACK_VERSION, commit='', date='', timestamp=0) - # first fetch data from gitarchivecfgfile, ignore if it is unexpanded - g = vd0.copy() - cp0 = RawConfigParser(vd0) - cp0.read(gitarchivecfgfile) - if len(cp0.get('DEFAULT', 'commit')) > 20: - g = cp0.defaults() - mx = re.search(r'\btag: v(\d[^,]*)', g.pop('refnames')) - if mx: - g['version'] = mx.group(1) - # then try to obtain version data from git. - gitdir = os.path.join(MYDIR, '.git') - if os.path.exists(gitdir) or 'GIT_DIR' in os.environ: - try: - g = gitinfo() - except OSError: - pass - # finally, check and update the active version file - cp = RawConfigParser() - cp.read(versioncfgfile) - d = cp.defaults() - rewrite = not d or (g['commit'] and ( - g['version'] != d.get('version') or g['commit'] != d.get('commit'))) - if rewrite: - cp.set('DEFAULT', 'version', g['version']) - cp.set('DEFAULT', 'commit', g['commit']) - cp.set('DEFAULT', 'date', g['date']) - cp.set('DEFAULT', 'timestamp', g['timestamp']) - with open(versioncfgfile, 'w') as fp: - cp.write(fp) - return cp - -versiondata = getversioncfg() - -with open(os.path.join(MYDIR, 'README.rst')) as fp: - long_description = fp.read() - -# define distribution +# Extensions not included in pyproject.toml setup_args = dict( - name = "diffpy.srreal", - version = versiondata.get('DEFAULT', 'version'), - packages = find_packages(os.path.join(MYDIR, 'src')), - package_dir = {'' : 'src'}, - test_suite = 'diffpy.srreal.tests', - include_package_data = True, ext_modules = [], - install_requires = [ - 'diffpy.structure', - ], - zip_safe = False, - - author = "Simon J.L. Billinge group", - author_email = "sb2896@columbia.edu", - maintainer = "Pavol Juhas", - maintainer_email = "pavol.juhas@gmail.com", - description = ("calculators for PDF, bond valence sum, and other " - "quantities based on atom pair interaction."), - long_description = long_description, - long_description_content_type = 'text/x-rst', - license = 'BSD-style license', - url = "https://github.com/diffpy/diffpy.srreal/", - keywords = "PDF BVS atom overlap calculator real-space", - classifiers = [ - # List of possible values at - # http://pypi.python.org/pypi?:action=list_classifiers - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: Education', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: BSD License', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: POSIX', - 'Operating System :: Unix', - 'Programming Language :: C++', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Topic :: Scientific/Engineering :: Chemistry', - 'Topic :: Scientific/Engineering :: Physics', - 'Topic :: Software Development :: Libraries', - ], ) + if __name__ == '__main__': setup_args['ext_modules'] = create_extensions() setup(**setup_args) From 27d12194f8f3a38a164a3f11001d1efeb29f0cbd Mon Sep 17 00:00:00 2001 From: = Date: Sat, 25 May 2024 20:04:21 -0400 Subject: [PATCH 3/5] Initial pyproject build --- setup.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 setup.py diff --git a/setup.py b/setup.py old mode 100755 new mode 100644 From de8579b12259557219bc194248042856cc8b91fb Mon Sep 17 00:00:00 2001 From: Sparky <59151395+Sparks29032@users.noreply.github.com> Date: Sat, 25 May 2024 23:08:42 -0400 Subject: [PATCH 4/5] Deprecation update pre-3.12 --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 556d9ccb..c37dd9b5 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ import glob from setuptools import setup from setuptools import Extension -from numpy.distutils.misc_util import get_numpy_include_dirs +import numpy as np # Use this version when git data are not available, like in git zip archive. @@ -27,7 +27,7 @@ 'libraries' : ['diffpy'], 'extra_compile_args' : ['-std=c++11'], 'extra_link_args' : [], - 'include_dirs' : get_numpy_include_dirs(), + 'include_dirs' : [np.get_include()], } # determine if we run with Python 3. From c71ed4e95e91c7822fd13362629ac254c22c7f9c Mon Sep 17 00:00:00 2001 From: Sparky <59151395+Sparks29032@users.noreply.github.com> Date: Tue, 20 Aug 2024 08:32:50 -0400 Subject: [PATCH 5/5] __array_wrap__ issue --- src/diffpy/srreal/tests/testoverlapcalculator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diffpy/srreal/tests/testoverlapcalculator.py b/src/diffpy/srreal/tests/testoverlapcalculator.py index 44d83312..5e144ac2 100644 --- a/src/diffpy/srreal/tests/testoverlapcalculator.py +++ b/src/diffpy/srreal/tests/testoverlapcalculator.py @@ -200,7 +200,7 @@ def test_gradients(self): tso0 = olc.totalsquareoverlap dx = 1e-8 rutile2 = loadDiffPyStructure('rutile.cif') - rutile2[2].xyz_cartn += [dx, 0.0, 0.0] + rutile2[2].xyz_cartn[0] += dx olc.eval(rutile2) g2nx = (olc.totalsquareoverlap - tso0) / dx self.assertAlmostEqual(g2[0], g2nx, 6)