Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c183a52
refactor(build): change pyproject to start migration to uv
gampnico Feb 9, 2026
79f2c93
fix: remove call to deprecated distutils package
gampnico Feb 12, 2026
3df5438
docs: add and reorder entry in whats-new
gampnico Feb 12, 2026
162caba
fix: syntax error
gampnico Feb 12, 2026
0010e9a
merge: merge branch 'refactor-uv-installation' into fix-distutils-str…
gampnico Feb 12, 2026
d1e9870
fix: remove distutils import
gampnico Feb 12, 2026
19d38aa
Revert "merge: merge branch 'refactor-uv-installation' into fix-distu…
gampnico Feb 12, 2026
efb01dc
fix: remove distutils import
gampnico Feb 12, 2026
4e56aec
fix: optional salem import, dev dependencies
gampnico Feb 12, 2026
3804869
merge: merge branch 'master' into refactor-uv-installation
gampnico Feb 23, 2026
2f40b9d
fix: incorrect readme link
gampnico Feb 24, 2026
ea01d44
fix: optional dependencies
gampnico Feb 24, 2026
a9d41af
refactor: add dev groups
gampnico Feb 25, 2026
0cc696f
docs: uv installation
gampnico Feb 25, 2026
c4c9146
docs: remove outdated installation instructions
gampnico Feb 25, 2026
b5d2e52
merge: merge branch 'master' into refactor-uv-installation
gampnico Feb 25, 2026
e163ee0
fix: update build number
gampnico Feb 25, 2026
576696b
feat: dynamic versioning
gampnico Feb 25, 2026
c0b4a80
refactor: migrate to hatchling, isolate uv, dynamic versioning
gampnico Feb 26, 2026
61b2ebb
merge: merge branch 'master' into refactor-uv-installation
gampnico Mar 2, 2026
9ad6790
fix: update included files to match changes to MANIFEST
gampnico Mar 2, 2026
ada4b03
fix: remove dependency pins
gampnico Mar 3, 2026
a268612
fix: address review comments
gampnico Mar 4, 2026
0b39d52
fix: revert changes to documentation
gampnico Mar 4, 2026
ca30d85
merge: merge branch 'master' into refactor-uv-installation
gampnico Mar 6, 2026
60b67c8
build: finalise toml, update whats-new
gampnico Mar 6, 2026
b4f592a
tests: sanity check for pytest-mpl-oggm
gampnico Mar 6, 2026
76599dd
build: switch to pypi release
gampnico Mar 6, 2026
6ae9965
merge: merge branch 'master' into refactor-uv-installation
gampnico Mar 6, 2026
7574902
fix: update authors metadata
gampnico Mar 9, 2026
4ff96b0
refactor: update dependency groups
gampnico Mar 9, 2026
ee2f964
fix: incorrect version detection now raises error
gampnico Mar 9, 2026
371413c
refactor: remove unnecessary code
gampnico Mar 9, 2026
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
123 changes: 63 additions & 60 deletions docs/installing-oggm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ are not trivial to install. The instructions below provide all the required
details and should work on Linux and Mac OS. See :ref:`install-troubleshooting`
if something goes wrong.

OGGM is fully `tested`_ with Python versions 3.9 to 3.11 on Linux.
OGGM is fully `tested`_ with Python versions 3.11 to 3.13 on Linux.
We do not test OGGM automatically on Mac OSX, but it should probably run
fine there as well.

Expand All @@ -33,59 +33,33 @@ fine there as well.
installing-oggm-windows.rst


For most users we recommend to
install Python and the package dependencies with the :ref:`conda package manager <conda-install>`,
in particular with ``mamba`` and ``conda-forge``.
For most users we recommend to install Python and the package dependencies with the :ref:`conda package manager <conda-install>`, in particular with ``mamba`` and ``conda-forge``.

.. _tested: https://github.com/OGGM/oggm/actions/workflows/run-tests.yml
.. _conda: https://conda.io/projects/conda/en/latest/user-guide/index.html
.. _pip: https://docs.python.org/3/installing/
.. _mamba: https://mamba.readthedocs.io


OGGM can be installed:
- as a library, if you don't want to modify its source code.This is recommended for most users.
- **stable**: this is the latest official release and has a fixed
version number (e.g. v1.6.2).
- **dev**: this is the development version.
It may contain new features and bug fixes, but will continue changing until its release.
- as an editable, if you want to make changes or develop the model. This is recommended for developers.

OGGM now supports installation with `pip`, `conda`, and `uv`.

Dependencies
------------

Here is a list of *all* dependencies of the OGGM model. If you want to use
OGGM's numerical models only (i.e. no GIS or preprocessing tools), refer to
`Install a minimal OGGM environment`_ below.

Standard SciPy stack:
- numpy
- scipy
- scikit-image
- pillow
- matplotlib
- pandas
- xarray
- dask
- joblib

Configuration file parsing tool:
- configobj

I/O:
- netcdf4
- pytables

GIS tools:
- shapely
- pyproj
- rasterio
- rioxarray
- geopandas

Testing:
- pytest
- pytest-mpl (for image tests only: `OGGM fork <https://github.com/OGGM/pytest-mpl>`_ required)

Other libraries:
- `salem <https://github.com/fmaussion/salem>`_
- `motionless <https://github.com/ryancox/motionless>`_

Optional:
- progressbar2 (displays the download progress)
- bottleneck (might speed up some xarray operations)
A full installation of OGGM requires GDAL.
The easiest way is:
.. code-block:: bash

sudo apt-get install gdal-bin libgdal-dev # Linux (Debian distros)
brew install gdal # MacOS

.. _conda-install:

Expand All @@ -112,9 +86,8 @@ which explains how to install ``mambaforge`` and
`this one <https://fabienmaussion.info/intro_to_programming/week_05/01-install-packages.html>`_
for installing packages.

We recommend to use `mamba`_ over conda as an
installation command. Mamba is a drop-in
replacement for all conda commands. If you feel like it, install mamba in your conda
We recommend to use `mamba`_ over conda as an installation command.
Mamba is a drop-in replacement for all conda commands. If you feel like it, install mamba in your conda
environment (``conda install -c conda-forge mamba``)
and replace all occurrences of ``conda`` with ``mamba`` in the instructions below.

Expand All @@ -128,24 +101,54 @@ and replace all occurrences of ``conda`` with ``mamba`` in the instructions belo
.. _miniconda: http://conda.pydata.org/miniconda.html
.. _mambaforge: https://github.com/conda-forge/miniforge#mambaforge

The simplest way: with an environment file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The fastest way: `uv` tool
~~~~~~~~~~~~~~~~~~~~~~~~~~

Copy the content of the file below into a file called ``environment.yml`` on your system
(alternatively, right-click -> "save as" on `this link <https://raw.githubusercontent.com/OGGM/oggm/master/docs/recommended_env.yml>`_).
For users who just want to run a notebook and don't need a dedicated environment.
This includes users who want to test OGGM before installing it, and teaching staff who want to use OGGM in a classroom.

.. include:: recommended_env.yml
:literal:
If you are new to Python and want to get started with OGGM as quickly as possible, we recommend using `uv`_.
You can install and run OGGM on a Jupyter server without polluting your base system or conda environment.

From the folder where you saved the file, run ``mamba env create -f environment.yml``.
.. _uv: _https://docs.astral.sh/uv/getting-started/installation/

This will create a new environment called ``oggm_env`` in your conda installation.
For more information about conda environments, visit the
`conda documentation on the topic <https://conda.io/projects/conda/en/latest/user-guide/concepts/environments.html>`_. Similarly,
visit `conda documentation on environment files <https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#creating-an-environment-from-an-environment-yml-file>`_
for more information about how to create an environment from a ``yml`` file.
Install `uv`:

Don't forget to :ref:`test-oggm` before using it!
.. code-block:: bash

wget -qO- https://astral.sh/uv/install.sh | sh

Launch a Jupyter notebook with OGGM fully installed:

.. code-block:: bash

uvx --with oggm jupyter lab

This installs a minimal version of OGGM into an isolated environment and runs a Jupyter server.

.. note:: This will not pollute your base system or conda environment.

The comfortable way: `conda` & `pip`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For users who don't want to use `uv` at all.

Create and activate a conda environment:

.. code-block:: bash
conda env create --n oggm_313 python=3.13
conda activate oggm_313

Install the latest **stable** release:

.. code-block:: bash
pip install oggm # for a minimal install
pip install oggm[full] # for a full install with all dependencies
uv pip install oggm # if you already have uv installed

Or install the latest **development** version:

.. code-block:: bash
pip install --upgrade git+https://github.com/OGGM/oggm.git

Install OGGM itself
~~~~~~~~~~~~~~~~~~~
Expand Down
4 changes: 4 additions & 0 deletions docs/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ Bug fixes
- Changed COPDEM data source (again) - this comes with good sides as the download
is much easier now (:pull:`1773`).
By `Fabien Maussion <https://github.com/fmaussion>`_
- Fixed ``ModuleNotFoundError`` caused by calling ``distutils`` which has been deprecated since Python 3.12.
Reimplements ``strtobool`` natively.
By `Nicolas Gampierakis <https://github.com/gampnico>`_.


Breaking changes
~~~~~~~~~~~~~~~~
Expand Down
35 changes: 34 additions & 1 deletion oggm/cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import sys
import glob
from collections import OrderedDict
from distutils.util import strtobool

import numpy as np
import pandas as pd
Expand Down Expand Up @@ -892,3 +891,37 @@ def add_to_basenames(basename, filename, docstr=''):
if '.' not in filename:
raise ValueError('The filename needs a proper file suffix!')
BASENAMES[basename] = (filename, docstr)


def strtobool(value: str) -> bool:
"""Convert a string representation of truth to True or False.

Reimplementation of distutils's ``strtobool``, which is deprecated
from Python 3.12.

Parameters
----------
value : bool
Any value to convert.

Returns
-------
bool
True for "y", "yes", "t", "true", "on", and "1"; False for "n", "no", "f", "false", "off", and "0".

Raises
------
ValueError if ``value`` is anything else.
"""

trues = {"yes", "true", "t", "y", "on", "1"}
falses = {"no", "false", "f", "n", "off", "0"}

if isinstance(value, str):
value = value.lower()
if value in trues:
return True
if value in falses:
return False

raise ValueError('Expected "%s"' % '", "'.join(trues | falses))
3 changes: 1 addition & 2 deletions oggm/tests/funcs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import shutil
from distutils.util import strtobool
import hashlib

import numpy as np
Expand Down Expand Up @@ -331,7 +330,7 @@ def patch_minimal_download_oggm_files(*args, **kwargs):

def use_multiprocessing():
try:
return strtobool(os.getenv("OGGM_TEST_MULTIPROC", "False"))
return cfg.strtobool(os.getenv("OGGM_TEST_MULTIPROC", "False"))
except BaseException:
return False

Expand Down
17 changes: 17 additions & 0 deletions oggm/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,23 @@ def test_cook_rgidf(self):
assert_allclose(df.cenlon, cgidf['Glc_Long'])
assert_allclose(df.rgi_area_km2, cgidf['Glc_Area'] * 1e-6, rtol=1e-3)

def test_strtobool(self):
trues = {"yes", "true", "t", "y", "on", "1"}
falses = {"no", "false", "f", "n", "off", "0"}
for value in trues:
assert isinstance(cfg.strtobool(value=value), bool)
assert cfg.strtobool(value=value)
assert cfg.strtobool(value=value.upper())

for value in falses:
assert isinstance(cfg.strtobool(value=value), bool)
assert not cfg.strtobool(value=value)
assert not cfg.strtobool(value=value.upper())

for value in {"ft", None, 2, True, False}:
with pytest.raises(ValueError):
cfg.strtobool(value=value)


class TestInitialize(unittest.TestCase):

Expand Down
5 changes: 4 additions & 1 deletion oggm/utils/_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@
import shapely.geometry as shpg
from shapely.ops import linemerge
from shapely.validation import make_valid
from salem.gis import Grid
try:
from salem.gis import Grid
except ImportError:
pass

# Optional libs
try:
Expand Down
Loading
Loading