Skip to content

Nexus: Move class variables to immutable types, remove constants created by str.split() - #6058

Merged
prckent merged 12 commits into
QMCPACK:developfrom
brockdyer03:constant-frozenset
Jul 31, 2026
Merged

Nexus: Move class variables to immutable types, remove constants created by str.split()#6058
prckent merged 12 commits into
QMCPACK:developfrom
brockdyer03:constant-frozenset

Conversation

@brockdyer03

Copy link
Copy Markdown
Contributor

Proposed changes

This PR takes several instances in Nexus of class variables, module variables, or constant collections and changing them from a mutable datatype to an immutable datatype. For example, many set-type variables were changed to frozenset, and many list variables were changed to tuple. This has the benefit of protection against accidental modification by a class method or user, and thus makes it less likely for errors to occur. In addition, in places where some constant variables are created using multiline-string splits, like the following:

machine_vars = set('''
    machine         account         machine_info    interactive_cores
    machine_mode    user
    '''.split())

these were moved to the appropriate collection type with constant string literals, e.g.

machine_vars = frozenset({
    'interactive_cores', 'machine_info', 'machine', 'machine_mode', 'user', 'account'
    })

This removes the runtime penalty incurred by splitting those strings, and can, in some cases, make test runs and initialization faster.

Additionally, a case was noticed in test_vasp_simulation.py::test_get_output_files where the test relied on order-specific lists, which was fixed to be order-agnostic.

What type(s) of changes does this code introduce?

  • Refactoring (no functional changes, no api changes)

Does this introduce a breaking change?

  • No

What systems has this change been tested on?

Laptop, Fedora Linux 43 (KDE Plasma Desktop Edition)
AMD Ryzen 7 PRO 7840U (8 cores, 16 logical processors)

Python        3.14.6
uv            0.11.26
cif2cell      2.1.0
coverage      7.15.0
h5py          3.16.0
matplotlib    3.11.0
numpy         2.5.1
pycifrw       4.4.6
pydot         4.0.1
pytest        9.1.1
pytest-cov    7.1.0
pytest-order  1.5.0
scipy         1.18.0
seekpath      2.2.1
spglib        2.7.0
sphinx        9.1.0

Checklist

    • I have read the pull request guidance and develop docs
    • This PR is up to date with the current state of 'develop'
    • This PR adds tests to cover any new code, or to catch a bug that is being fixed
    • Documentation has been added (if appropriate)

@brockdyer03
brockdyer03 requested a review from jtkrogel July 27, 2026 19:07
@brockdyer03 brockdyer03 self-assigned this Jul 27, 2026
@brockdyer03 brockdyer03 added enhancement nexus cleanup For cleanling legacy lines of code refactor optimization python Pull requests that update python code labels Jul 27, 2026

@jtkrogel jtkrogel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes for nested/repeated tuple reconstruction and discouraged style for unnecessarily set construction for short list queries of if statement literals.

Comment thread nexus/nexus/examples/qmcpack/rsqmc_misc/diamond_lowdin/lowdin.py
Comment thread nexus/nexus/__init__.py
Comment thread nexus/nexus/developer_tools.py
Comment thread nexus/nexus/qmcpack_input.py
Comment thread nexus/nexus/qmcpack_input.py
Comment thread nexus/nexus/qmcpack_input.py
Comment thread nexus/nexus/qmcpack_quantity_analyzers.py Outdated
Comment thread nexus/nexus/xmlreader.py
@brockdyer03
brockdyer03 requested a review from jtkrogel July 29, 2026 14:23

@jtkrogel jtkrogel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marked all small set literals as resolved.

Some old comments outstanding; a couple now added.

Comment thread nexus/nexus/basisset.py

crystal_lmap = {0:'s',1:'sp',2:'p',3:'d',4:'f'}
crystal_lmap_reverse = dict(s=0,sp=1,p=2,d=3,f=4)
crystal_lmap = MappingProxyType({0:'s',1:'sp',2:'p',3:'d',4:'f'})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really necessary? Please don't tell me you are going to decorate every dict in the codebase this way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only class variables. The MappingProxyType class just makes the dict immutable and changes nothing else about its interface. If you'd prefer, I can just add the ClassVar type annotation?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a roundabout frozendict?

setattr(cls,k,v)
for v in ['attributes','elements','parameters','attribs','costs','h5tags']:
names = getattr(cls,v)
names = list(getattr(cls,v))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just seems wrong. If sequence elements are intended to be mutated (as here), tuple is not the appropriate type (for attributes, elements, etc)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought so too initially, but the function there is basically only supposed to post-process the class attributes. Once the function is called, they should be "finalized" and not touched again.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we really have to. It just unclear and unintuitive.

jtkrogel
jtkrogel previously approved these changes Jul 30, 2026

@jtkrogel jtkrogel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good enough

@prckent

prckent commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Test this please

@prckent
prckent enabled auto-merge July 31, 2026 16:03
@prckent
prckent disabled auto-merge July 31, 2026 16:57
@prckent

prckent commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Test this please

@prckent prckent left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reapproving based on prior reviews

@prckent
prckent merged commit 0990d7b into QMCPACK:develop Jul 31, 2026
50 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cleanup For cleanling legacy lines of code enhancement nexus optimization python Pull requests that update python code refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants