Skip to content

Commit

Permalink
Merge branch 'master' into HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
bjodah committed Apr 23, 2024
2 parents 665ce84 + 9792c65 commit 38a2094
Show file tree
Hide file tree
Showing 15 changed files with 173 additions and 195 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/lint_python.yml
Expand Up @@ -17,12 +17,14 @@ jobs:
- run: bandit --recursive --skip B101,B102,B110,B112,B307,B404,B603,B607 .
- run: black --check . || true
- run: codespell --ignore-words-list="ans,claus,fith,nam,nd,ond,serie,te"
- run: flake8 . --count --max-complexity=66 --max-line-length=118
- run: flake8 . --count --max-complexity=66 --max-line-length=129
--show-source --statistics
- run: pip install flake8-bugbear flake8-comprehensions flake8-return flake8-simplify
- run: flake8 . --count --exit-zero --max-complexity=66 --max-line-length=118
- run: flake8 . --count --exit-zero --max-complexity=66 --max-line-length=129
--show-source --statistics
- run: isort --check-only --profile black . || true
- run: pip install setuptools
- run: pip install --editable . || pip install .
- run: mkdir --parents --verbose .mypy_cache
- run: mypy --ignore-missing-imports --install-types --non-interactive . || true
- run: shopt -s globstar && pyupgrade --py37-plus **/*.py || true
108 changes: 55 additions & 53 deletions .drone.yml → .woodpecker.yaml
@@ -1,16 +1,18 @@
pipeline:
restore-cache:
image: drillster/drone-volume-cache
restore: true
mount:
- ./cache-ci/pyusrb
- ./cache-ci/conda_packages
- ./cache-ci/pip_cache
volumes:
- /tmp/cache:/cache
ttl: 90 # liftetime in days
when:
- event: [pull_request, tag, cron, push]

install:
steps:

- name: restore-cache
image: bjodah/bjodahimg20dot:21.8.a
commands:
- curl ftp://chempy:$${ARTIFACTS_PASS}@$${FTP_SERVER}/cache/cache-ci.tar | tar x
secrets: [ ARTIFACTS_PASS, FTP_SERVER ]
when:
- event: push
repo: bjodah/chempy

- name: install
image: bjodah/bjodahimg20dot:21.8.a
environment:
- CC=gcc-11
Expand All @@ -25,17 +27,17 @@ pipeline:
- export CPATH=$SUNDBASE/include:$CPATH
- export LIBRARY_PATH=$SUNDBASE/lib
- export LD_LIBRARY_PATH=$SUNDBASE/lib
- python3 -m pip install --cache-dir $CACHE_ROOT/pip_cache --user --upgrade-strategy=eager --upgrade cython
- python3 -m pip install --cache-dir $CACHE_ROOT/pip_cache --user -e .[all]
- python3 -c "import pycvodes; import pyodesys; import pygslodeiv2" # debug this CI config
- git fetch -tq
- python3 setup.py sdist # test pip installable sdist (checks MANIFEST.in)
- git archive -o dist/chempy-head.zip HEAD # test pip installable zip (symlinks break)
- mkdir -p deploy/public_html/branches/${DRONE_BRANCH}
- cp dist/chempy-* deploy/public_html/branches/${DRONE_BRANCH}/
- mkdir -p deploy/public_html/branches/${CI_COMMIT_BRANCH}
- cp dist/chempy-* deploy/public_html/branches/${CI_COMMIT_BRANCH}/

test-suite:
- name: test-suite
image: bjodah/bjodahimg20dot:21.8.a
group: testing
environment:
- CC=gcc-11
- CXX=g++-11
Expand All @@ -52,19 +54,20 @@ pipeline:
- bash -c '[[ $(python3 setup.py --version) =~ ^[0-9]+.* ]]'
- ./scripts/run_tests.sh --cov chempy --cov-report html
- ./scripts/coverage_badge.py htmlcov/ htmlcov/coverage.svg
- cp -r htmlcov/ deploy/public_html/branches/${DRONE_BRANCH}/
- cp -r htmlcov/ deploy/public_html/branches/${CI_COMMIT_BRANCH}/
- ./.ci/grep-for-merge-blocking-token.sh
- export CHEMPY_DEPRECATION_FILTER=ignore
- python3 -m virtualenv /tmp/test_sdist
- python3 -m virtualenv /tmp/test_git_archive
- cd deploy/public_html/branches/${DRONE_BRANCH}
- cd deploy/public_html/branches/${CI_COMMIT_BRANCH}
- unset CHEMPY_SKIP_NO_TESTS # I can't get pip to install extras when using local file...
- bash -c "source /tmp/test_sdist/bin/activate; pip install --cache-dir $CACHE_ROOT/pip_cache file://$(realpath $(eval ls chempy-*.tar.gz))#chempy[all] pytest; pytest --pyargs chempy"
- bash -c "source /tmp/test_git_archive/bin/activate; pip install --cache-dir $CACHE_ROOT/pip_cache file://$(realpath chempy-head.zip)#chempy[all] pytest; pytest --pyargs chempy"
depends_on:
- install

render-notebooks:
- name: render-notebooks
image: bjodah/bjodahimg20dot:21.8.a
group: testing
environment:
- CHEMPY_DEPRECATION_FILTER=ignore
- SUNDBASE=/opt/sundials-5.7.0-release
Expand All @@ -79,20 +82,11 @@ pipeline:
- ./scripts/render_notebooks.sh
- ./.ci/grep-for-binary-data.sh
- mv index.html index.ipynb.html
# - (cd examples/; for f in bokeh_*.py; do python3 -m bokeh html $f; done)
- cp -r index.* examples/ "deploy/public_html/branches/${DRONE_BRANCH}"

# conda-recipe:
# image: bjodah/bjodahimg20dot:21.8.a
# group: testing
# commands:
# - export CONDA_PKGS_DIRS=$(pwd)/cache-ci/conda_packages
# - git fetch -tq
# - PATH=/opt/miniconda3/bin:$PATH conda config --add channels bjodah # sym, pyodesys, pyneqsys
# - PATH=/opt/miniconda3/bin:$PATH conda build --output-folder "deploy/public_html/branches/${DRONE_BRANCH}" conda-recipe
# - (cd $CONDA_PKGS_DIRS; find . -maxdepth 1 -type d -not -path . -not -path .. | xargs rm -r)
- cp -r index.* examples/ "deploy/public_html/branches/${CI_COMMIT_BRANCH}"
depends_on:
- install

compile-documentation:
- name: compile-documentation
image: bjodah/bjodahimg20dot:21.8.a
environment:
- CHEMPY_DEPRECATION_FILTER=ignore
Expand All @@ -104,26 +98,34 @@ pipeline:
- export LD_LIBRARY_PATH=$SUNDBASE/lib
- ./scripts/generate_docs.sh
- cp LICENSE doc/_build/html/
- cp -r doc/_build/html/ deploy/public_html/branches/${DRONE_BRANCH}
- cp -r doc/_build/html/ deploy/public_html/branches/${CI_COMMIT_BRANCH}
depends_on:
- test-suite
- render-notebooks

rebuild-cache:
image: drillster/drone-volume-cache
rebuild: true
mount:
# - ./cache-ci/sund-3.2.1
- ./cache-ci/pyusrb
- ./cache-ci/conda_packages
- ./cache-ci/pip_cache
volumes:
- /tmp/cache:/cache
- name: rebuild-cache
image: bjodah/bjodahimg20dot:21.8.a
commands:
- find ./cache-ci/ -type f -mtime +90 -exec rm {} \;
- tar cf cache-ci.tar ./cache-ci/
- curl -T cache-ci.tar ftp://chempy:$${ARTIFACTS_PASS}@$${FTP_SERVER}/cache/
secrets: [ ARTIFACTS_PASS, FTP_SERVER ]
when:
- event: push
repo: bjodah/chempy
depends_on:
- compile-documentation

deploy:
image: drillster/drone-rsync
- name: deploy-public-html
image: bjodah/bjodahimg20dot:21.8.a
commands:
- tar czf chempy-${CI_COMMIT_BRANCH}.tar.gz ./deploy/public_html
- curl -T chempy-${CI_COMMIT_BRANCH}.tar.gz ftp://chempy:$${ARTIFACTS_PASS}@$${FTP_SERVER}/public_html/
secrets: [ ARTIFACTS_PASS, FTP_SERVER ]
when:
event: [push]
hosts: [ "hera.physchem.kth.se" ]
port: 22
user: chempy
secrets: [ rsync_key ] # secret only set fro event "push" not "pull_request"
source: ./deploy/public_html
target: ~/
- event: push
repo: bjodah/chempy
depends_on:
- compile-documentation


20 changes: 5 additions & 15 deletions README.rst
Expand Up @@ -3,13 +3,13 @@ ChemPy

.. image:: https://github.com/bjodah/chempy/actions/workflows/lint_python.yml/badge.svg
:target: https://github.com/bjodah/chempy/actions/workflows/lint_python.yml
:alt: Build status
:alt: Github Actions CI status
.. image:: https://hackspett.bjodah.se/api/badges/1/status.svg
:target: https://hackspett.bjodah.se/repos/1
:alt: Woodpecker CI status
.. image:: https://img.shields.io/pypi/v/chempy.svg
:target: https://pypi.python.org/pypi/chempy
:alt: PyPI version
.. image:: https://img.shields.io/badge/python-3.8,3.9-blue.svg
:target: https://www.python.org/
:alt: Python version
.. image:: https://img.shields.io/pypi/l/chempy.svg
:target: https://github.com/bjodah/chempy/blob/master/LICENSE
:alt: License
Expand Down Expand Up @@ -374,16 +374,6 @@ literature with relevance in chemistry. Here is how you use one of these formula
[H2O] = 55.18 M (at 35 °C)
Run notebooks using binder
~~~~~~~~~~~~~~~~~~~~~~~~~~
Using only a web-browser (and an internet connection) it is possible to explore the
notebooks here: (by the courtesy of the people behind mybinder)

.. image:: http://mybinder.org/badge.svg
:target: https://mybinder.org/v2/gh/bjodah/chempy/f5f2546e79e165ba8fb258fc87d83a7fbdcbad64?filepath=index.ipynb
:alt: Binder


Citing
------
If you make use of ChemPy in e.g. academic work you may cite the following peer-reviewed publication:
Expand All @@ -395,7 +385,7 @@ If you make use of ChemPy in e.g. academic work you may cite the following peer-
Depending on what underlying solver you are using you should also cite the appropriate paper
(you can look at the list of references in the JOSS article). If you need to reference,
in addition to the paper, a specific point version of ChemPy (for e.g. reproducibility)
you can get per-version DOIs from the zendodo archive:
you can get per-version DOIs from the zenodo archive:

.. image:: https://zenodo.org/badge/8840/bjodah/chempy.svg
:target: https://zenodo.org/badge/latestdoi/8840/bjodah/chempy
Expand Down
2 changes: 1 addition & 1 deletion chempy/_release.py
@@ -1 +1 @@
__version__ = "0.8.1.dev0+git"
__version__ = "0.9.0.dev0+git"
22 changes: 15 additions & 7 deletions chempy/chemistry.py
Expand Up @@ -98,6 +98,16 @@ def __eq__(self, other):
return False
return True

def __hash__(self) -> int:
hashed_values = []
for key in self.attrs:
value = getattr(self, key)
if isinstance(value, dict):
hashed_values.append(hash(tuple(sorted(value.items()))))
else:
hashed_values.append(hash(value))
return sum(hashed_values)

@property
def charge(self):
"""Convenience property for accessing ``composition[0]``"""
Expand Down Expand Up @@ -446,9 +456,8 @@ def _init_stoich(container):
if isinstance(container, set):
container = {k: 1 for k in container}
container = container or {}
if (
type(container) == dict
): # we don't want isinstance here in case of OrderedDict
if type(container) == dict: # noqa
# we don't want isinstance here in case of OrderedDict
container = OrderedDict(sorted(container.items(), key=lambda kv: kv[0]))
return container

Expand Down Expand Up @@ -1446,11 +1455,10 @@ def balance_stoichiometry(
substances = OrderedDict(
[(k, substance_factory(k)) for k in substances.split()]
)
if (
type(reactants) == set
): # we don't want isinstance since it might be "OrderedSet"
if type(reactants) == set: # noqa
# we don't want isinstance since it might be "OrderedSet"
reactants = sorted(reactants)
if type(products) == set:
if type(products) == set: # noqa
products = sorted(products)
subst_keys = list(reactants) + list(products)

Expand Down
2 changes: 2 additions & 0 deletions chempy/tests/test_chemistry.py
Expand Up @@ -40,6 +40,8 @@ def test_Substance():
assert s.composition == {0: 1, 1: 1}
assert s.charge == 1
assert abs(s.mass - 1.008) < 1e-3
assert s in {s: 1}
assert hash(s) != hash(Substance.from_formula("He"))


def test_Substance__2():
Expand Down
24 changes: 17 additions & 7 deletions chempy/util/parsing.py
Expand Up @@ -95,7 +95,7 @@ def _get_formula_parser():
| '{' formula '}'
| '[' formula ']' ) count prime charge?
formula :: term+
hydrate :: '.' count? formula
hydrate :: ( '..' | '\u00B7' ) count? formula
state :: '(' ( 's' | 'l' | 'g' | 'aq' | 'cr' ) ')'
compound :: count formula hydrate? state?
Expand All @@ -114,7 +114,7 @@ def _get_formula_parser():
| '{' formula '}'
| '[' formula ']' ) count prime charge?
formula :: term+
hydrate :: '..' count? formula
hydrate :: ( '..' | '\u00B7' ) count? formula
state :: '(' ( 's' | 'l' | 'g' | 'aq' | 'cr' ) ')'
compound :: count formula hydrate? state?
"""
Expand Down Expand Up @@ -334,7 +334,7 @@ def _parse_stoich(stoich):

_unicode_mapping = {k + "-": v + "-" for k, v in zip(_greek_letters, _greek_u)}
_unicode_mapping["."] = "⋅"
_unicode_infix_mapping = {"..": "·"}
_unicode_infix_mapping = {"..": "\u00b7"} # 0x00b7: '·'

_html_mapping = {k + "-": "&" + k + ";-" for k in _greek_letters}
_html_mapping["."] = "&sdot;"
Expand Down Expand Up @@ -379,14 +379,19 @@ def formula_to_composition(
True
>>> formula_to_composition('Na2CO3..7H2O') == {11: 2, 6: 1, 8: 10, 1: 14}
True
>>> formula_to_composition('UO2.3') == {92: 1, 8: 2.3}
True
"""
if prefixes is None:
prefixes = _latex_mapping.keys()

stoich_tok, chg_tok = _formula_to_parts(formula, prefixes, suffixes)[:2]
tot_comp = {}
parts = stoich_tok.split("..")
if '\u00b7' in stoich_tok:
parts = stoich_tok.split('\u00b7')
else:
parts = stoich_tok.split("..")

for idx, stoich in enumerate(parts):
if idx == 0:
Expand Down Expand Up @@ -532,7 +537,10 @@ def _formula_to_format(
suffixes=("(s)", "(l)", "(g)", "(aq)"),
):
parts = _formula_to_parts(formula, prefixes.keys(), suffixes)
stoichs = parts[0].split("..")
if '\u00b7' in parts[0]:
stoichs = parts[0].split('\u00b7')
else:
stoichs = parts[0].split("..")
string = ""
for idx, stoich in enumerate(stoichs):
if idx == 0:
Expand Down Expand Up @@ -600,9 +608,11 @@ def formula_to_latex(formula, prefixes=None, infixes=None, **kwargs):
)


_unicode_sub = {}
_unicode_sub = {
".": ".",
}

for k, v in enumerate("₀₁₂₃₄₅₆₇₈₉"):
for k, v in enumerate("₀₁₂₃₄₅₆₇₈₉."):
_unicode_sub[str(k)] = v

_unicode_sup = {
Expand Down

0 comments on commit 38a2094

Please sign in to comment.