owid-datautils 0.6.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. owid_datautils-0.6.1/.bumpversion.cfg +12 -0
  2. owid_datautils-0.6.1/.codecov.yml +13 -0
  3. owid_datautils-0.6.1/.github/workflows/python-package.yml +52 -0
  4. owid_datautils-0.6.1/.gitignore +141 -0
  5. owid_datautils-0.6.1/.pre-commit-config.yaml +15 -0
  6. owid_datautils-0.6.1/.readthedocs.yaml +23 -0
  7. owid_datautils-0.6.1/LICENSE +21 -0
  8. owid_datautils-0.6.1/Makefile +8 -0
  9. owid_datautils-0.6.1/PKG-INFO +20 -0
  10. owid_datautils-0.6.1/README.md +85 -0
  11. owid_datautils-0.6.1/docs/Makefile +20 -0
  12. owid_datautils-0.6.1/docs/_static/favicon.ico +0 -0
  13. owid_datautils-0.6.1/docs/_static/owid.png +0 -0
  14. owid_datautils-0.6.1/docs/apidoc-templates/module.rst_t +8 -0
  15. owid_datautils-0.6.1/docs/apidoc-templates/package.rst_t +52 -0
  16. owid_datautils-0.6.1/docs/apidoc-templates/toc.rst_t +7 -0
  17. owid_datautils-0.6.1/docs/conf.py +90 -0
  18. owid_datautils-0.6.1/docs/index.rst +12 -0
  19. owid_datautils-0.6.1/docs/make.bat +35 -0
  20. owid_datautils-0.6.1/owid/datautils/__init__.py +3 -0
  21. owid_datautils-0.6.1/owid/datautils/checks.py +1 -0
  22. owid_datautils-0.6.1/owid/datautils/common.py +44 -0
  23. owid_datautils-0.6.1/owid/datautils/dataframes.py +739 -0
  24. owid_datautils-0.6.1/owid/datautils/decorators.py +91 -0
  25. owid_datautils-0.6.1/owid/datautils/format/__init__.py +7 -0
  26. owid_datautils-0.6.1/owid/datautils/format/numbers.py +304 -0
  27. owid_datautils-0.6.1/owid/datautils/google/__init__.py +7 -0
  28. owid_datautils-0.6.1/owid/datautils/google/api.py +136 -0
  29. owid_datautils-0.6.1/owid/datautils/google/config.py +117 -0
  30. owid_datautils-0.6.1/owid/datautils/google/sheets.py +134 -0
  31. owid_datautils-0.6.1/owid/datautils/io/__init__.py +14 -0
  32. owid_datautils-0.6.1/owid/datautils/io/archive.py +84 -0
  33. owid_datautils-0.6.1/owid/datautils/io/df.py +163 -0
  34. owid_datautils-0.6.1/owid/datautils/io/json.py +78 -0
  35. owid_datautils-0.6.1/owid/datautils/ui.py +32 -0
  36. owid_datautils-0.6.1/owid/datautils/web.py +106 -0
  37. owid_datautils-0.6.1/pyproject.toml +57 -0
  38. owid_datautils-0.6.1/tests/__init__.py +0 -0
  39. owid_datautils-0.6.1/tests/format/__init__.py +3 -0
  40. owid_datautils-0.6.1/tests/format/test_numbers.py +221 -0
  41. owid_datautils-0.6.1/tests/google/__init__.py +0 -0
  42. owid_datautils-0.6.1/tests/google/test_api.py +29 -0
  43. owid_datautils-0.6.1/tests/google/test_config.py +114 -0
  44. owid_datautils-0.6.1/tests/google/test_sheets.py +89 -0
  45. owid_datautils-0.6.1/tests/io/test_archive.py +215 -0
  46. owid_datautils-0.6.1/tests/io/test_df.py +228 -0
  47. owid_datautils-0.6.1/tests/io/test_json.py +56 -0
  48. owid_datautils-0.6.1/tests/mocks.py +12 -0
  49. owid_datautils-0.6.1/tests/test_dataframes.py +1651 -0
  50. owid_datautils-0.6.1/tests/test_decorators.py +72 -0
  51. owid_datautils-0.6.1/tests/test_ui.py +28 -0
  52. owid_datautils-0.6.1/tests/test_web.py +89 -0
  53. owid_datautils-0.6.1/uv.lock +2248 -0
@@ -0,0 +1,12 @@
1
+ [bumpversion]
2
+ current_version = 0.5.3
3
+ commit = True
4
+ tag = True
5
+
6
+ [bumpversion:file:pyproject.toml]
7
+
8
+ [bumpversion:file:README.md]
9
+
10
+ [bumpversion:file:owid/datautils/__init__.py]
11
+
12
+ [bumpversion:file:docs/conf.py]
@@ -0,0 +1,13 @@
1
+ coverage:
2
+ status:
3
+ project:
4
+ default:
5
+ target: auto
6
+ # adjust accordingly based on how flaky your tests are
7
+ # this allows a 10% drop from the previous base commit coverage
8
+ threshold: 3%
9
+ patch:
10
+ default:
11
+ target: auto
12
+ threshold: 3%
13
+ base: auto
@@ -0,0 +1,52 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ build:
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ python-version: ["3.8", "3.9", "3.10", "3.11"]
15
+
16
+ runs-on: ubuntu-latest
17
+
18
+ steps:
19
+ - uses: actions/checkout@v2
20
+
21
+ - name: Set up Python ${{ matrix.python-version }}
22
+ uses: actions/setup-python@v2
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+
26
+ - name: Install packages
27
+ run: |
28
+ make .venv
29
+
30
+ - name: Check formatting
31
+ run: |
32
+ make check-formatting
33
+
34
+ - name: Lint
35
+ run: |
36
+ make lint
37
+
38
+ - name: Check typing
39
+ run: |
40
+ make check-typing
41
+
42
+ - name: Unit test
43
+ run: |
44
+ make report-coverage
45
+
46
+ - name: "Coverage: Upload to codecov.io"
47
+ uses: codecov/codecov-action@v2
48
+ with:
49
+ fail_ci_if_error: true
50
+ verbose: true
51
+ files: coverage.xml
52
+ token: ${{ secrets.CODECOV_TOKEN }}
@@ -0,0 +1,141 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ # Usually these files are written by a python script from a template
32
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ target/
76
+
77
+ # Jupyter Notebook
78
+ .ipynb_checkpoints
79
+
80
+ # IPython
81
+ profile_default/
82
+ ipython_config.py
83
+
84
+ # pyenv
85
+ .python-version
86
+
87
+ # pipenv
88
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
90
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
91
+ # install all needed dependencies.
92
+ #Pipfile.lock
93
+
94
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95
+ __pypackages__/
96
+
97
+ # Celery stuff
98
+ celerybeat-schedule
99
+ celerybeat.pid
100
+
101
+ # SageMath parsed files
102
+ *.sage.py
103
+
104
+ # Environments
105
+ .env
106
+ .venv
107
+ env/
108
+ venv/
109
+ ENV/
110
+ env.bak/
111
+ venv.bak/
112
+
113
+ # Spyder project settings
114
+ .spyderproject
115
+ .spyproject
116
+
117
+ # Rope project settings
118
+ .ropeproject
119
+
120
+ # mkdocs documentation
121
+ /site
122
+
123
+ # mypy
124
+ .mypy_cache/
125
+ .dmypy.json
126
+ dmypy.json
127
+
128
+ # Pyre type checker
129
+ .pyre/
130
+
131
+ # PyCharm config
132
+ .idea
133
+
134
+ # Mac hidden files
135
+ .DS_Store
136
+
137
+ # reports (coverage, linting)
138
+ .reports/
139
+
140
+ # Google
141
+ client_secret*
@@ -0,0 +1,15 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: format
5
+ name: format
6
+ entry: make format
7
+ language: system
8
+ - id: lint
9
+ name: lint
10
+ entry: make lint
11
+ language: system
12
+ - id: check-typing
13
+ name: check-typing
14
+ entry: make check-typing
15
+ language: system
@@ -0,0 +1,23 @@
1
+ # Read the Docs configuration file
2
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3
+
4
+ # Required
5
+ version: 2
6
+
7
+ # Set the version of Python and other tools you might need
8
+ build:
9
+ os: ubuntu-20.04
10
+ tools: {python: "3.8"}
11
+ jobs:
12
+ pre_create_environment:
13
+ - asdf plugin add poetry
14
+ - asdf install poetry latest
15
+ - asdf global poetry latest
16
+ - poetry config virtualenvs.create false
17
+ post_install:
18
+ - poetry install
19
+
20
+ # Build documentation in the docs/ directory with Sphinx
21
+ sphinx:
22
+ configuration: docs/conf.py
23
+ fail_on_warning: true
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Global Change Data Lab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,8 @@
1
+ #
2
+ # Makefile
3
+ #
4
+
5
+
6
+ include ../../default.mk
7
+
8
+ SRC = owid tests
@@ -0,0 +1,20 @@
1
+ Metadata-Version: 2.4
2
+ Name: owid-datautils
3
+ Version: 0.6.1
4
+ Summary: Data utils library by the Data Team at Our World in Data
5
+ Author-email: Our World in Data <tech@ourworldindata.org>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Keywords: data cleaning,data processing,data utils,our world in data
9
+ Requires-Python: <4.0,>=3.10
10
+ Requires-Dist: boto3>=1.38.23
11
+ Requires-Dist: click>=8.1.7
12
+ Requires-Dist: colorama>=0.4.4
13
+ Requires-Dist: gdown>=4.5.2
14
+ Requires-Dist: gsheets>=0.6.1
15
+ Requires-Dist: pandas>=2.2.3
16
+ Requires-Dist: py7zr>=0.22.0
17
+ Requires-Dist: pyarrow>=18.0.0
18
+ Requires-Dist: pydrive2>=1.15.0
19
+ Requires-Dist: structlog>=21.5.0
20
+ Requires-Dist: urllib3<2
@@ -0,0 +1,85 @@
1
+ # owid-datautils
2
+
3
+ ![version](https://img.shields.io/badge/version-0.6.0-blue)
4
+ ![version](https://img.shields.io/badge/python-3.10|3.11|3.12|3.13-blue.svg?&logo=python&logoColor=yellow)
5
+ [![Build status](https://badge.buildkite.com/caba621fb64f2c7dcc692a474e68f4ead21e6ba6ee151fe3b6.svg)](https://buildkite.com/our-world-in-data/owid-datautils-unit-tests)
6
+ [![Documentation Status](https://readthedocs.org/projects/owid-datautils/badge/?version=latest)](https://docs.owid.io/projects/owid-datautils/en/latest/?badge=latest)
7
+
8
+ **owid-datautils** is a library to support the work of the Data Team at Our World in Data.
9
+
10
+ ## Install
11
+
12
+ ```
13
+ pip install owid-datautils
14
+ ```
15
+
16
+ Or install the latest development version directly from GitHub:
17
+
18
+ ```
19
+ pip install git+https://github.com/owid/etl.git#subdirectory=lib/datautils
20
+ ```
21
+
22
+ ## Development
23
+
24
+ ### Pre-requisites
25
+
26
+ You need Python 3.10+, `UV` and `make` installed.
27
+
28
+ ### Install in development mode
29
+
30
+ ```
31
+ make .venv
32
+ ```
33
+
34
+ ### Test the code
35
+
36
+ Run:
37
+
38
+ ```
39
+ # run all unit tests and CI checks
40
+ make test
41
+ ```
42
+
43
+ ### Other useful commands
44
+
45
+ #### Code Quality
46
+
47
+ ```
48
+ make check
49
+ ```
50
+
51
+ Format, lint, and typecheck changed files from master branch using `ruff` and `pyright`.
52
+
53
+ ```
54
+ make format
55
+ ```
56
+
57
+ Format code using `ruff`.
58
+
59
+ ```
60
+ make lint
61
+ ```
62
+
63
+ Lint code using `ruff`.
64
+
65
+ ```
66
+ make check-typing
67
+ ```
68
+
69
+ Run type checking using `pyright`.
70
+
71
+ #### Coverage
72
+
73
+ ```
74
+ make coverage
75
+ ```
76
+
77
+ Run unit tests with coverage reporting.
78
+
79
+ #### Versioning
80
+
81
+ ```
82
+ make bump [part]
83
+ ```
84
+
85
+ Upgrade version in all files where it appears. `[part]` can be `patch`, `minor` ad `major`.
@@ -0,0 +1,20 @@
1
+ # Minimal makefile for Sphinx documentation
2
+ #
3
+
4
+ # You can set these variables from the command line, and also
5
+ # from the environment for the first two.
6
+ SPHINXOPTS ?=
7
+ SPHINXBUILD ?= sphinx-build
8
+ SOURCEDIR = .
9
+ BUILDDIR = _build
10
+
11
+ # Put it first so that "make" without argument is like "make help".
12
+ help:
13
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14
+
15
+ .PHONY: help Makefile
16
+
17
+ # Catch-all target: route all unknown targets to Sphinx using the new
18
+ # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19
+ %: Makefile
20
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@@ -0,0 +1,8 @@
1
+ {%- if show_headings %}
2
+ {{- ["owid.", basename] | join('') | e | heading }}
3
+
4
+ {% endif -%}
5
+ .. automodule:: {{ qualname }}
6
+ {%- for option in automodule_options %}
7
+ :{{ option }}:
8
+ {%- endfor %}
@@ -0,0 +1,52 @@
1
+ {%- macro automodule(modname, options) -%}
2
+ .. automodule:: {{ modname }}
3
+ {%- for option in options %}
4
+ :{{ option }}:
5
+ {%- endfor %}
6
+ {%- endmacro %}
7
+
8
+ {%- macro toctree(docnames) -%}
9
+ .. toctree::
10
+ :maxdepth: {{ maxdepth }}
11
+ {% for docname in docnames %}
12
+ {{ docname }}
13
+ {%- endfor %}
14
+ {%- endmacro %}
15
+
16
+ {%- if is_namespace %}
17
+ {{- [pkgname, "namespace"] | join(" ") | e | heading }}
18
+ {% else %}
19
+ {{- pkgname | e | heading }}
20
+ {% endif %}
21
+
22
+ {%- if is_namespace %}
23
+ .. py:module:: {{ pkgname }}
24
+ {% endif %}
25
+
26
+ {%- if modulefirst and not is_namespace %}
27
+ {{ automodule(pkgname, automodule_options) }}
28
+ {% endif %}
29
+
30
+ {%- if subpackages %}
31
+
32
+
33
+ {{ toctree(subpackages) }}
34
+ {% endif %}
35
+
36
+ {%- if submodules %}
37
+ {% if separatemodules %}
38
+ {{ toctree(submodules) }}
39
+ {% else %}
40
+ {%- for submodule in submodules %}
41
+ {% if show_headings %}
42
+ {{- submodule | e | heading(2) }}
43
+ {% endif %}
44
+ {{ automodule(submodule, automodule_options) }}
45
+ {% endfor %}
46
+ {%- endif %}
47
+ {%- endif %}
48
+
49
+ {%- if not modulefirst and not is_namespace %}
50
+
51
+ {{ automodule(pkgname, automodule_options) }}
52
+ {% endif %}
@@ -0,0 +1,7 @@
1
+ {{ header | heading }}
2
+
3
+ .. toctree::
4
+ :maxdepth: {{ maxdepth }}
5
+ {% for docname in docnames %}
6
+ {{ docname }}
7
+ {%- endfor %}
@@ -0,0 +1,90 @@
1
+ # Configuration file for the Sphinx documentation builder.
2
+ #
3
+ # This file only contains a selection of the most common options. For a full
4
+ # list see the documentation:
5
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html
6
+
7
+ # -- Path setup --------------------------------------------------------------
8
+
9
+ # If extensions (or modules to document with autodoc) are in another directory,
10
+ # add these directories to sys.path here. If the directory is relative to the
11
+ # documentation root, use os.path.abspath to make it absolute, like shown here.
12
+ #
13
+ import os
14
+ import sys
15
+
16
+ sys.path.insert(0, os.path.abspath(os.path.join("../owid/")))
17
+
18
+ # -- Project information -----------------------------------------------------
19
+
20
+ project = "owid-datautils"
21
+ copyright = "2022, Our World in Data"
22
+ author = "Our World in Data"
23
+
24
+ # The full version, including alpha/beta/rc tags
25
+ release = "0.5.3"
26
+
27
+
28
+ # -- General configuration ---------------------------------------------------
29
+
30
+ # Add any Sphinx extension module names here, as strings. They can be
31
+ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
32
+ # ones.
33
+ extensions = [
34
+ "sphinx.ext.autodoc",
35
+ "sphinx.ext.autosummary",
36
+ "sphinx.ext.napoleon",
37
+ "sphinx.ext.viewcode",
38
+ ]
39
+
40
+ # Add any paths that contain templates here, relative to this directory.
41
+ templates_path = ["_templates"]
42
+
43
+ # List of patterns, relative to source directory, that match files and
44
+ # directories to ignore when looking for source files.
45
+ # This pattern also affects html_static_path and html_extra_path.
46
+ exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "api/modules.rst"]
47
+
48
+
49
+ # -- Options for HTML output -------------------------------------------------
50
+
51
+ # The theme to use for HTML and HTML Help pages. See the documentation for
52
+ # a list of builtin themes.
53
+ #
54
+ html_theme = "furo"
55
+
56
+ html_theme_options = {
57
+ "sidebar_hide_name": True,
58
+ }
59
+
60
+ # Add any paths that contain custom static files (such as style sheets) here,
61
+ # relative to this directory. They are copied after the builtin static files,
62
+ # so a file named "default.css" will overwrite the builtin "default.css".
63
+ html_static_path = ["_static"]
64
+
65
+
66
+ html_logo = "_static/owid.png"
67
+ html_favicon = "_static/favicon.ico"
68
+
69
+ autodoc_default_flags = [
70
+ "members",
71
+ "undoc-members",
72
+ "private-members",
73
+ "special-members",
74
+ "inherited-members",
75
+ "show-inheritance",
76
+ ]
77
+
78
+ html_context = {
79
+ "display_github": True, # Integrate GitHub
80
+ "github_user": "owid", # Username
81
+ "github_repo": "owid-datautils-py", # Repo name
82
+ "github_version": "main", # Version
83
+ "conf_py_path": "docs/", # Path in the checkout to the docs root
84
+ }
85
+
86
+ ## API docs
87
+ from sphinx.ext.apidoc import main
88
+
89
+ # uv run sphinx-apidoc --help
90
+ main(["-f", "-e", "-t", "apidoc-templates", "-P", "-o", "api", "../owid/"])
@@ -0,0 +1,12 @@
1
+ .. owid-datautils documentation master file, created by
2
+ sphinx-quickstart on Wed Jun 1 23:00:03 2022.
3
+ You can adapt this file completely to your liking, but it should at least
4
+ contain the root `toctree` directive.
5
+
6
+ owid-datautils
7
+ ==========================================
8
+
9
+ .. toctree::
10
+ :maxdepth: 2
11
+
12
+ owid.datautils <api/datautils>
@@ -0,0 +1,35 @@
1
+ @ECHO OFF
2
+
3
+ pushd %~dp0
4
+
5
+ REM Command file for Sphinx documentation
6
+
7
+ if "%SPHINXBUILD%" == "" (
8
+ set SPHINXBUILD=sphinx-build
9
+ )
10
+ set SOURCEDIR=.
11
+ set BUILDDIR=_build
12
+
13
+ %SPHINXBUILD% >NUL 2>NUL
14
+ if errorlevel 9009 (
15
+ echo.
16
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
17
+ echo.installed, then set the SPHINXBUILD environment variable to point
18
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
19
+ echo.may add the Sphinx directory to PATH.
20
+ echo.
21
+ echo.If you don't have Sphinx installed, grab it from
22
+ echo.https://www.sphinx-doc.org/
23
+ exit /b 1
24
+ )
25
+
26
+ if "%1" == "" goto help
27
+
28
+ %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29
+ goto end
30
+
31
+ :help
32
+ %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33
+
34
+ :end
35
+ popd
@@ -0,0 +1,3 @@
1
+ """Library to support the work of the Data Team at Our World in Data."""
2
+
3
+ __version__ = "0.5.3"
@@ -0,0 +1 @@
1
+ """Utils related to sanity checks of datasets."""
@@ -0,0 +1,44 @@
1
+ """Common objects shared by other modules."""
2
+
3
+ import warnings
4
+ from typing import Any, List, Set, Union, cast
5
+
6
+
7
+ class ExceptionFromDocstring(Exception):
8
+ """Exception that returns its own docstring, if no message is explicitly given."""
9
+
10
+ def __init__(self, exception_message: Union[str, None] = None, *args: Any):
11
+ super().__init__(exception_message or self.__doc__, *args)
12
+
13
+
14
+ class ExceptionFromDocstringWithKwargs(Exception):
15
+ """Exception that returns its own docstring, if no message is explicitly given."""
16
+
17
+ def __init__(self, exception_message: Union[str, None] = None, *args: Any, **kwargs: Any):
18
+ text = cast(str, exception_message or self.__doc__)
19
+ if kwargs:
20
+ additional_text = ", ".join([f"{key}: {value}" for key, value in kwargs.items()])
21
+ if additional_text is not None:
22
+ text += " " + additional_text
23
+ super().__init__(text, *args)
24
+
25
+
26
+ def warn_on_list_of_entities(
27
+ list_of_entities: Union[List[Any], Set[Any]], warning_message: str, show_list: bool
28
+ ) -> None:
29
+ """Raise a warning with a custom message, and optionally print a list of affected elements.
30
+
31
+ Parameters
32
+ ----------
33
+ list_of_entities : list or set
34
+ Elements to optionally print one by one (only relevant if show_list is True).
35
+ warning_message : str
36
+ Warning message.
37
+ show_list : bool
38
+ True to print a list of affected entities.
39
+
40
+ """
41
+ warnings.warn(warning_message)
42
+ if show_list:
43
+ print(warning_message)
44
+ print("\n".join(["* " + str(entity) for entity in list_of_entities]))