Skip to content

Renamed pacakge from qcio to qcdata - #99

Merged
coltonbh merged 2 commits into
masterfrom
feature-rename-to-qcdata
Mar 26, 2026
Merged

Renamed pacakge from qcio to qcdata#99
coltonbh merged 2 commits into
masterfrom
feature-rename-to-qcdata

Conversation

@coltonbh

Copy link
Copy Markdown
Collaborator

No description provided.

@coltonbh
coltonbh force-pushed the feature-rename-to-qcdata branch from 37531a0 to 623f861 Compare March 26, 2026 17:42
@coltonbh
coltonbh force-pushed the feature-rename-to-qcdata branch from 623f861 to e12a400 Compare March 26, 2026 18:03
@coltonbh
coltonbh requested a review from Copilot March 26, 2026 18:45
@coltonbh
coltonbh merged commit 2149e58 into master Mar 26, 2026
10 of 11 checks passed
@coltonbh
coltonbh deleted the feature-rename-to-qcdata branch March 26, 2026 18:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR renames the Python package from qcio to qcdata, updates imports/references across the codebase, and introduces/updates compatibility layers so existing downstream users can transition with minimal breakage.

Changes:

  • Renames project/package metadata and updates dependencies, tooling, and CI to use qcdata.
  • Refactors output container models to make ProgramOutput primary again and demote Results to a deprecated alias (with compatibility shims).
  • Updates tests, docs, and serialized artifacts (e.g., XYZ comment prefixes) to the new qcdata naming.

Reviewed changes

Copilot reviewed 60 out of 65 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
uv.lock Updates locked dependency names to qcdata.
pyproject.toml Renames the distribution to qcdata and updates project URLs/tooling config.
scripts/tests.sh Updates coverage target from qcio to qcdata.
.github/workflows/test.yaml Updates CI coverage target to qcdata.
.github/workflows/publish-to-pypi.yaml Updates PyPI project URL to qcdata.
src/qcdata/init.py Adds qcdata package entrypoint and exports/public API.
src/qcio/init.py Replaces old qcio entrypoint with a deprecated compatibility shim.
src/qcdata/helper_types.py Introduces shared annotated helper types (e.g., SerializableNDArray).
src/qcdata/utils.py Updates module docstring to qcdata naming.
src/qcdata/view.py Updates viewer code to use qcdata types and terminology.
src/qcdata/qcel.py Updates QCElemental interop imports and naming (qcioqcdata).
src/qcdata/py.typed Marks the package as typed for type checkers.
src/qcdata/models/init.py Re-exports models, switching from results to outputs module.
src/qcdata/models/base_models.py Renames base model class to QCDataBaseModel and updates docstrings.
src/qcdata/models/data.py Splits/clarifies “structured data” models and updates naming.
src/qcdata/models/outputs.py Adds ProgramOutput as primary output container and Results deprecated alias.
src/qcdata/models/results.py Adds compatibility module for legacy qcdata.models.results imports.
src/qcdata/models/inputs.py Updates docstring examples to qcdata.models import paths.
src/qcdata/models/structure.py Updates base class/imports and changes XYZ comment prefixes to qcdata_*.
src/qcdata/models/utils.py Updates TYPE_CHECKING import to qcdata.
tests/conftest.py Renames fixtures and imports to use ProgramOutput/qcdata.
tests/test_package_api.py Updates wildcard import test to qcdata.
tests/test_calc_input.py Updates imports from qcio to qcdata.
tests/test_file_input.py Updates imports from qcio to qcdata.
tests/test_files.py Updates imports from qcio.models to qcdata.models.
tests/test_conformer_search_data.py Updates imports from qcio to qcdata.
tests/test_qcel.py Updates qcel helper imports to qcdata.qcel.
tests/test_view.py Updates imports and output type (ResultsProgramOutput).
tests/test_serialization.py Updates serialization tests to ProgramOutput.
tests/test_structure.py Updates imports and expected XYZ prefix strings to qcdata_*.
tests/test_optimization_data.py Updates tests to use ProgramOutput terminology and qcdata_* prefixes.
tests/test_outputs.py Adds dedicated tests for output-container behaviors under ProgramOutput.
tests/test_single_point_data.py Adds focused tests for SinglePointData/Wavefunction numpy coercions and validators.
tests/test_results.py Removes old combined results/output tests (superseded by new split tests).
tests/data/structures.py Updates fixture imports to qcdata.
tests/data/caffeine.xyz Updates XYZ comment prefixes from qcio_* to qcdata_*.
tests/data/multi.xyz Updates XYZ comment prefixes from qcio_* to qcdata_*.
mkdocs.yml Renames site/project references and restructures API nav (outputs/data/results alias).
docs/CNAME Updates docs domain from qcio.* to qcdata.*.
docs/index.md Updates docs landing page branding, badges, links, and install snippets to qcdata.
docs/why.md Updates “Why” page references from qcio to qcdata.
docs/dev-docs/dev-decisions.md Updates design decision doc references from Results to ProgramOutput.
docs/visualizations/overview.md Updates install snippets and terminology to qcdata/ProgramOutput.
docs/visualizations/structure.ipynb Updates notebook imports and embedded XYZ prefixes to qcdata_*.
docs/visualizations/U1-_mmff94s_180-opt-terachem-thf.json Updates embedded filenames/strings from qcio_* to qcdata_*.
docs/api/overview.md Updates API mental model section to qcdata and new outputs/data separation.
docs/api/inputs.md Updates API docs to reference qcdata and ProgramOutput.
docs/api/outputs.md Adds a new Outputs API page for ProgramOutput + deprecated Results alias.
docs/api/data.md Adds a new Data API page for structured output payload models.
docs/api/results.md Refactors Results API page to document it as deprecated alias.
docs/api/structure.md Updates directive targets to qcdata.*.
docs/api/files.md Updates directive target to qcdata.Files.
docs/api/model.md Updates directive target to qcdata.Model.
docs/api/provenance.md Updates directive target to qcdata.Provenance.
docs/api/lengthunit.md Updates directive target to qcdata.LengthUnit.
docs/api/calctype.md Updates directive target to qcdata.CalcType.
docs/api/view.md Updates directive target to qcdata.view.
docs/api/utils.md Updates directive targets to qcdata.json_dumps / qcdata.to_multi_xyz.
docs/api/qciobasemodel.md Removes old QCIO base-model API doc page.
docs/api/qcdatabasemodel.md Adds new QCData base-model API doc page.
README.md Updates README branding/links to qcdata, and revises narrative toward ProgramOutput/Data.
CHANGELOG.md Adds changelog notes about the rename and model/test/doc reorganization.
.vscode/settings.json Updates VS Code spelling dictionary entry (QCIOQCDATA).
Comments suppressed due to low confidence (4)

tests/test_structure.py:200

  • This parametrized test block is named like it covers backwards-compatibility parsing of XYZ comment keys, but the cases were updated from qcio_charge/qcio_multiplicity to qcdata_*. If you intend to keep compatibility with existing qcio_*-prefixed XYZ files, it would be good to keep/add explicit qcio_* cases here (in addition to the new qcdata_* ones).
    src/qcdata/models/data.py:160
  • The validation error message still says "SinglePointResults requires ..." but the class is SinglePointData. Updating the message would avoid confusion for users seeing this ValidationError.
    README.md:45
  • The README quickstart uses CalcInput and CompositeCalcInput, but those symbols don’t appear to exist in the current qcdata package (the codebase uses ProgramInput / DualProgramInput). As-is, the documented examples will fail for users. Either update the docs to the supported API, or add/restore aliases with deprecation guidance.
#### CalcInput - Core input object for a single QC calculation.

```python
from qcdata import Structure, CalcInput
# xyz files or saved Structure objects can be opened from disk
caffeine = Structure.open("caffeine.xyz")
# Define the program input
prog_input = CalcInput(
    structure=caffeine,

src/qcdata/models/structure.py:336

  • Structure.from_xyz now only recognizes qcdata_ / qcdata__identifiers_ prefixes. This breaks loading older XYZ files written with the previous qcio_ prefixes. If backwards compatibility is a goal (there’s a qcio shim elsewhere), consider accepting both qcio_* and qcdata_* prefixes when parsing comments.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/api/results.md
Comment on lines 6 to 7
options:
members: false

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

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

The mkdocstrings options block is not indented under the ::: qcdata.Results directive, so it likely won’t be applied (and will render as plain text). Please indent options:/members: to match the convention used elsewhere in docs/api/*.

Suggested change
options:
members: false
options:
members: false

Copilot uses AI. Check for mistakes.
Comment thread docs/api/data.md
Comment on lines +8 to +19
options:
members: false

::: qcdata.OptimizationData
options:
members:
- structures
- final_structure
- energies
- final_energy
- to_xyz
- save

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

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

The mkdocstrings option blocks in this file (e.g., for SinglePointData / OptimizationData) are not indented under their ::: directives, which likely prevents mkdocstrings from applying them. Please indent options: and its fields to match other API doc pages.

Suggested change
options:
members: false
::: qcdata.OptimizationData
options:
members:
- structures
- final_structure
- energies
- final_energy
- to_xyz
- save
options:
members: false
::: qcdata.OptimizationData
options:
members:
- structures
- final_structure
- energies
- final_energy
- to_xyz
- save

Copilot uses AI. Check for mistakes.
Comment on lines +115 to +140
@model_validator(mode="after")
def ensure_traceback_on_failure(self) -> Self:
if self.success is False:
assert self.traceback is not None, (
"A traceback must be provided for failed calculations."
)
return self

@model_validator(mode="after")
def _ensure_structured_results_on_success(self) -> Self:
"""Ensure structured results are provided for successful, non FileInputs."""
if self.success is True and isinstance(self.input_data, ProgramInput):
assert type(self.data) is not Files, (
"Structured results must be provided for successful, non FileInput "
"calculations."
)
return self

@model_validator(mode="after")
def ensure_primary_result_on_success(self) -> Self:
if type(self.data) is SinglePointData:
calctype_val = self.input_data.calctype.value # type: ignore
assert getattr(self.data, calctype_val) is not None, (
f"Missing the primary result: {calctype_val}."
)
return self

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

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

These validators use assert for runtime validation. assert statements are stripped when Python is run with optimizations (-O), which would silently disable critical validation (e.g., missing traceback on failures). Prefer raising ValueError/TypeError instead of assert in validators.

Copilot uses AI. Check for mistakes.
Comment thread tests/test_structure.py
Comment on lines 31 to 37
caffeine = Structure.open(test_data_dir / "caffeine.xyz")
caffeine.save(tmp_path / "caffeine_copy.xyz")
caffeine_copy = Structure.open(tmp_path / "caffeine_copy.xyz")
assert caffeine_copy.symbols == caffeine.symbols
assert np.allclose(caffeine.geometry, qcio_structures.caffeine.geometry, rtol=1e-9)
assert np.allclose(caffeine.geometry, qcdata_structures.caffeine.geometry, rtol=1e-9)
assert caffeine_copy.multiplicity == caffeine.multiplicity
assert caffeine_copy.charge == caffeine.charge

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

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

In test_to_file_xyz, the geometry assertion compares caffeine.geometry against the fixture geometry, but it never verifies caffeine_copy.geometry. This means the test won’t catch geometry serialization/deserialization regressions in the saved copy. Consider asserting against caffeine_copy.geometry here.

Copilot uses AI. Check for mistakes.
Comment thread docs/api/outputs.md
Comment on lines +6 to +13
options:
members: false

## Deprecated Alias

::: qcdata.Results
options:
members: false

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

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

The mkdocstrings directive options here aren’t indented under the ::: qcdata.ProgramOutput directive (unlike other API docs pages in this repo). As written, options:/members: will likely render as plain text and not configure mkdocstrings. Please indent these lines to match the pattern used in e.g. docs/api/structure.md.

Suggested change
options:
members: false
## Deprecated Alias
::: qcdata.Results
options:
members: false
options:
members: false
## Deprecated Alias
::: qcdata.Results
options:
members: false

Copilot uses AI. Check for mistakes.
@@ -1,16 +1,16 @@
Being able to quickly and easily visualize results is critical for efficient scientific work. `qcio` come with build-in visualizations for all objects.
Being able to quickly and easily visualize results is critical for efficient scientific work. `qcdata` come with build-in visualizations for all objects.

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

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

Grammar: "qcdata come with build-in visualizations" should be "qcdata comes with built-in visualizations".

Suggested change
Being able to quickly and easily visualize results is critical for efficient scientific work. `qcdata` come with build-in visualizations for all objects.
Being able to quickly and easily visualize results is critical for efficient scientific work. `qcdata` comes with built-in visualizations for all objects.

Copilot uses AI. Check for mistakes.
Comment thread docs/why.md
# Why qcdata?

Other data structure package for quantum chemistry exist such as [QCElemental](https://github.com/MolSSI/QCElemental) and [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/index.html). I often found these libraries were too heavy weight or too feature poor for most of what I needed. I also found their APIs to be somewhat unintuitive and often cumbersome to use. `qcio` is designed to be easy to use, easy to reason about, and provide a unified format for diverse quantum chemistry calculations.
Other data structure package for quantum chemistry exist such as [QCElemental](https://github.com/MolSSI/QCElemental) and [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/index.html). I often found these libraries were too heavy weight or too feature poor for most of what I needed. I also found their APIs to be somewhat unintuitive and often cumbersome to use. `qcdata` is designed to be easy to use, easy to reason about, and provide a unified format for diverse quantum chemistry calculations.

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

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

Grammar: "Other data structure package ... exist" should be plural, and "heavy weight"/"feature poor" are typically written "heavyweight"/"feature-poor".

Suggested change
Other data structure package for quantum chemistry exist such as [QCElemental](https://github.com/MolSSI/QCElemental) and [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/index.html). I often found these libraries were too heavy weight or too feature poor for most of what I needed. I also found their APIs to be somewhat unintuitive and often cumbersome to use. `qcdata` is designed to be easy to use, easy to reason about, and provide a unified format for diverse quantum chemistry calculations.
Other data structure packages for quantum chemistry exist such as [QCElemental](https://github.com/MolSSI/QCElemental) and [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/index.html). I often found these libraries were too heavyweight or too feature-poor for most of what I needed. I also found their APIs to be somewhat unintuitive and often cumbersome to use. `qcdata` is designed to be easy to use, easy to reason about, and provide a unified format for diverse quantum chemistry calculations.

Copilot uses AI. Check for mistakes.
Comment on lines +52 to +71
if "stdout" in payload:
warnings.warn(
"The 'stdout' attribute has been renamed to 'logs'. Please update your "
"code accordingly.",
category=FutureWarning,
stacklevel=2,
)
if "logs" not in payload:
payload["logs"] = payload.pop("stdout")

if "results" in payload:
warnings.warn(
"The 'results' attribute has been renamed to 'data'. Please update "
"your code accordingly.",
category=FutureWarning,
stacklevel=2,
)
if isinstance(payload["results"], dict):
payload["data"] = payload.pop("results")

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

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

In the backwards-compatibility pre-validator, legacy keys like stdout and results are only removed in some cases. If a payload contains both stdout+logs (or non-dict results), the legacy key will remain and then fail validation because QCDataBaseModel forbids extra fields. Consider always pop()-ing stdout/results when present (and mapping them onto logs/data only when the new field is absent).

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +85
if "files" in payload:
warnings.warn(
"The 'files' attribute has been moved to 'data.files'. Please "
"update your code accordingly.",
category=FutureWarning,
stacklevel=2,
)
if isinstance(payload["data"], dict):
data_files_dict = payload["data"].get("files", {})
else:
data_files_dict = payload["data"].files

data_files_dict.update(**payload.pop("files"))

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

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

_backwards_compatibility assumes payload["data"] exists when files is present. If an old payload includes top-level files without data/results (or results was non-dict and not migrated), this will raise KeyError inside the validator and mask the real validation problem. Suggest guarding for missing data and/or migrating resultsdata for all types before trying to merge files.

Copilot uses AI. Check for mistakes.
Comment on lines +162 to +171
def __repr_args__(self) -> list[tuple[str, Any]]:
"""Exclude stdout and traceback from the repr and ensure success is first."""
args = super().__repr_args__()
filtered_args = [
(key, value if key not in {"stdout", "traceback"} else "<...>")
for key, value in args
]
success_arg = [(key, value) for key, value in filtered_args if key == "success"]
other_args = [(key, value) for key, value in filtered_args if key != "success"]
return success_arg + other_args

Copilot AI Mar 26, 2026

Copy link

Choose a reason for hiding this comment

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

__repr_args__ masks keys {"stdout", "traceback"}, but this model’s field is logs (and stdout is only a compatibility property). As written, large logs strings will still be included in the repr. Consider filtering/masking logs (and traceback) instead.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants