data-manipulation 0.50__tar.gz → 0.54__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 (137) hide show
  1. {data_manipulation-0.50 → data_manipulation-0.54}/.gitignore +6 -5
  2. data_manipulation-0.54/CHANGELOG.md +92 -0
  3. {data_manipulation-0.50 → data_manipulation-0.54}/CODE_OF_CONDUCT.md +9 -6
  4. {data_manipulation-0.50 → data_manipulation-0.54}/PKG-INFO +12 -9
  5. {data_manipulation-0.50 → data_manipulation-0.54}/README.md +6 -1
  6. data_manipulation-0.54/RELEASE.md +101 -0
  7. data_manipulation-0.54/conftest.py +24 -0
  8. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/__init__.py +0 -4
  9. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/_version.py +3 -3
  10. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/base.py +62 -135
  11. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/beautifulsoup_.py +26 -25
  12. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/boto3_.py +23 -19
  13. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/cryptography_.py +23 -19
  14. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/kerberos_.py +9 -8
  15. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/mysql_connector_python_.py +33 -27
  16. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/openldap_.py +6 -10
  17. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/pandas_.py +144 -288
  18. data_manipulation-0.54/data_manipulation/polars_.py +87 -0
  19. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/postgres_.py +22 -42
  20. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/pyspark_.py +70 -124
  21. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/smtplib_.py +19 -12
  22. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation/sqlalchemy_.py +39 -44
  23. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation.egg-info/PKG-INFO +12 -9
  24. data_manipulation-0.54/data_manipulation.egg-info/SOURCES.txt +64 -0
  25. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation.egg-info/requires.txt +4 -2
  26. data_manipulation-0.54/data_manipulation.egg-info/scm_file_list.json +60 -0
  27. data_manipulation-0.54/data_manipulation.egg-info/scm_version.json +8 -0
  28. data_manipulation-0.54/docs/api/base.md +3 -0
  29. data_manipulation-0.54/docs/api/beautifulsoup_.md +3 -0
  30. data_manipulation-0.54/docs/api/boto3_.md +3 -0
  31. data_manipulation-0.54/docs/api/cryptography_.md +3 -0
  32. data_manipulation-0.54/docs/api/kerberos_.md +3 -0
  33. data_manipulation-0.54/docs/api/mysql_connector_python_.md +3 -0
  34. data_manipulation-0.54/docs/api/pandas_.md +3 -0
  35. data_manipulation-0.54/docs/api/polars_.md +3 -0
  36. data_manipulation-0.54/docs/api/postgres_.md +3 -0
  37. data_manipulation-0.54/docs/api/pyspark_.md +3 -0
  38. data_manipulation-0.54/docs/api/smtplib_.md +3 -0
  39. data_manipulation-0.54/docs/api/sqlalchemy_.md +3 -0
  40. data_manipulation-0.54/docs/changelog.md +92 -0
  41. data_manipulation-0.50/docs/_build/html/_sources/getting-started.rst.txt → data_manipulation-0.54/docs/getting-started.md +1 -2
  42. data_manipulation-0.54/docs/hooks.py +10 -0
  43. data_manipulation-0.54/docs/index.md +12 -0
  44. data_manipulation-0.54/mkdocs.yml +36 -0
  45. data_manipulation-0.54/pyproject.toml +95 -0
  46. {data_manipulation-0.50 → data_manipulation-0.54}/setup.sh +17 -10
  47. data_manipulation-0.54/tests/conftest.py +36 -0
  48. data_manipulation-0.54/tests/test_base.py +124 -0
  49. data_manipulation-0.54/tests/test_beautifulsoup.py +40 -0
  50. data_manipulation-0.54/tests/test_boto3.py +22 -0
  51. data_manipulation-0.54/tests/test_cryptography.py +43 -0
  52. data_manipulation-0.54/tests/test_kerberos.py +26 -0
  53. data_manipulation-0.54/tests/test_mysql.py +27 -0
  54. data_manipulation-0.54/tests/test_openldap.py +29 -0
  55. data_manipulation-0.54/tests/test_pandas.py +128 -0
  56. data_manipulation-0.54/tests/test_postgres.py +32 -0
  57. data_manipulation-0.54/tests/test_pyspark.py +64 -0
  58. data_manipulation-0.54/tests/test_smtplib.py +35 -0
  59. data_manipulation-0.54/tests/test_sqlalchemy.py +43 -0
  60. data_manipulation-0.50/Makefile +0 -144
  61. data_manipulation-0.50/data_manipulation/django_.py +0 -165
  62. data_manipulation-0.50/data_manipulation/flask_.py +0 -31
  63. data_manipulation-0.50/data_manipulation/geopandas_.py +0 -78
  64. data_manipulation-0.50/data_manipulation/prometheus_.py +0 -0
  65. data_manipulation-0.50/data_manipulation.egg-info/SOURCES.txt +0 -98
  66. data_manipulation-0.50/docs/.nojekyll +0 -0
  67. data_manipulation-0.50/docs/Makefile +0 -153
  68. data_manipulation-0.50/docs/_build/doctrees/commands.doctree +0 -0
  69. data_manipulation-0.50/docs/_build/doctrees/data_manipulation.doctree +0 -0
  70. data_manipulation-0.50/docs/_build/doctrees/environment.pickle +0 -0
  71. data_manipulation-0.50/docs/_build/doctrees/getting-started.doctree +0 -0
  72. data_manipulation-0.50/docs/_build/doctrees/index.doctree +0 -0
  73. data_manipulation-0.50/docs/_build/doctrees/modules.doctree +0 -0
  74. data_manipulation-0.50/docs/_build/html/.buildinfo +0 -4
  75. data_manipulation-0.50/docs/_build/html/.nojekyll +0 -0
  76. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/base.html +0 -576
  77. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/beautifulsoup_.html +0 -184
  78. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/boto3_.html +0 -268
  79. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/cryptography_.html +0 -225
  80. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/django_.html +0 -258
  81. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/geopandas_.html +0 -159
  82. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/kerberos_.html +0 -170
  83. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/mysql_connector_python_.html +0 -310
  84. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/openldap_.html +0 -172
  85. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/pandas_.html +0 -867
  86. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/pyspark_.html +0 -551
  87. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/smtplib_.html +0 -163
  88. data_manipulation-0.50/docs/_build/html/_modules/data_manipulation/sqlalchemy_.html +0 -274
  89. data_manipulation-0.50/docs/_build/html/_modules/index.html +0 -89
  90. data_manipulation-0.50/docs/_build/html/_sources/commands.rst.txt +0 -10
  91. data_manipulation-0.50/docs/_build/html/_sources/data_manipulation.rst.txt +0 -141
  92. data_manipulation-0.50/docs/_build/html/_sources/index.rst.txt +0 -28
  93. data_manipulation-0.50/docs/_build/html/_sources/modules.rst.txt +0 -7
  94. data_manipulation-0.50/docs/_build/html/_static/basic.css +0 -906
  95. data_manipulation-0.50/docs/_build/html/_static/doctools.js +0 -149
  96. data_manipulation-0.50/docs/_build/html/_static/documentation_options.js +0 -13
  97. data_manipulation-0.50/docs/_build/html/_static/file.png +0 -0
  98. data_manipulation-0.50/docs/_build/html/_static/language_data.js +0 -192
  99. data_manipulation-0.50/docs/_build/html/_static/minus.png +0 -0
  100. data_manipulation-0.50/docs/_build/html/_static/nature.css +0 -245
  101. data_manipulation-0.50/docs/_build/html/_static/plus.png +0 -0
  102. data_manipulation-0.50/docs/_build/html/_static/pygments.css +0 -75
  103. data_manipulation-0.50/docs/_build/html/_static/searchtools.js +0 -635
  104. data_manipulation-0.50/docs/_build/html/_static/sphinx_highlight.js +0 -154
  105. data_manipulation-0.50/docs/_build/html/commands.html +0 -128
  106. data_manipulation-0.50/docs/_build/html/data_manipulation.html +0 -2299
  107. data_manipulation-0.50/docs/_build/html/genindex.html +0 -509
  108. data_manipulation-0.50/docs/_build/html/getting-started.html +0 -113
  109. data_manipulation-0.50/docs/_build/html/index.html +0 -155
  110. data_manipulation-0.50/docs/_build/html/modules.html +0 -206
  111. data_manipulation-0.50/docs/_build/html/objects.inv +0 -0
  112. data_manipulation-0.50/docs/_build/html/py-modindex.html +0 -171
  113. data_manipulation-0.50/docs/_build/html/search.html +0 -98
  114. data_manipulation-0.50/docs/_build/html/searchindex.js +0 -1
  115. data_manipulation-0.50/docs/commands.rst +0 -10
  116. data_manipulation-0.50/docs/conf.py +0 -273
  117. data_manipulation-0.50/docs/data_manipulation.rst +0 -141
  118. data_manipulation-0.50/docs/getting-started.rst +0 -6
  119. data_manipulation-0.50/docs/index.html +0 -1
  120. data_manipulation-0.50/docs/index.rst +0 -28
  121. data_manipulation-0.50/docs/make.bat +0 -190
  122. data_manipulation-0.50/docs/modules.rst +0 -7
  123. data_manipulation-0.50/models/.gitkeep +0 -0
  124. data_manipulation-0.50/notebooks/.gitkeep +0 -0
  125. data_manipulation-0.50/pyproject.toml +0 -55
  126. data_manipulation-0.50/references/.gitkeep +0 -0
  127. data_manipulation-0.50/reports/.gitkeep +0 -0
  128. data_manipulation-0.50/reports/figures/.gitkeep +0 -0
  129. data_manipulation-0.50/test_environment.py +0 -26
  130. data_manipulation-0.50/tox.ini +0 -3
  131. {data_manipulation-0.50 → data_manipulation-0.54}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  132. {data_manipulation-0.50 → data_manipulation-0.54}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  133. {data_manipulation-0.50 → data_manipulation-0.54}/CONTRIBUTING.md +0 -0
  134. {data_manipulation-0.50 → data_manipulation-0.54}/LICENSE +0 -0
  135. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation.egg-info/dependency_links.txt +0 -0
  136. {data_manipulation-0.50 → data_manipulation-0.54}/data_manipulation.egg-info/top_level.txt +0 -0
  137. {data_manipulation-0.50 → data_manipulation-0.54}/setup.cfg +0 -0
@@ -51,15 +51,15 @@ coverage.xml
51
51
  # Django stuff:
52
52
  *.log
53
53
 
54
- # Sphinx documentation
55
- # docs/_build/
56
- !docs/build
54
+ # MkDocs documentation
55
+ /site/
57
56
 
58
57
  # PyBuilder
59
58
  target/
60
59
 
61
60
  # DotEnv configuration
62
61
  .env
62
+ .pypirc
63
63
 
64
64
  # Database
65
65
  *.db
@@ -93,7 +93,8 @@ target/
93
93
  .mypy_cache/
94
94
 
95
95
  # custom
96
+ .opencode
97
+ .specstory
96
98
  build.sh
97
- install_packages.sh
98
99
  docs/README*
99
- .opencode
100
+ install_packages.sh
@@ -0,0 +1,92 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased]
4
+
5
+ ### Removed
6
+
7
+ - **`django_` module** - removed entirely (breaking change). The Django helpers
8
+ (`init_django`, `get_django_countries_dict`, `django_validate_email`,
9
+ `django_validate_url`, `django_validate_phone`) now live in the
10
+ [`django-util`](https://github.com/shawnngtq/django-util) package:
11
+ `django_util.utility` (`init_django`, `get_django_countries_dict`) and
12
+ `django_util.validators` (the `django_validate_*` functions). `data_manipulation`
13
+ no longer depends on Django. This warrants a major version bump on release.
14
+
15
+ - **`pandas_.clean_none()`** - function has been removed.
16
+ Migrate to pandas built-ins:
17
+
18
+ ```python
19
+ df = df.replace(r"^\s*$", np.nan, regex=True)
20
+ df = df.where(pd.notnull(df), None)
21
+ ```
22
+
23
+ - **`pandas_.config_pandas_display()`** - function has been removed.
24
+ Set display options directly:
25
+
26
+ ```python
27
+ pd.set_option("display.max_columns", 500)
28
+ pd.set_option("display.max_colwidth", 500)
29
+ pd.set_option("display.expand_frame_repr", True)
30
+ ```
31
+
32
+ - **`prometheus_` module** - was an empty placeholder; removed from
33
+ the public API and from `__init__` imports.
34
+
35
+ ### Changed
36
+
37
+ - **`base.get_none_variation()`** - now returns a `frozenset` of 7
38
+ lowercase canonical strings instead of a 72-item list of case
39
+ permutations. Use `.casefold()` for membership checks:
40
+
41
+ ```python
42
+ # before
43
+ if value in get_none_variation():
44
+ ...
45
+ # after
46
+ if isinstance(value, str) and value.casefold() in get_none_variation():
47
+ ...
48
+ ```
49
+
50
+ - **`pyspark_.group_count()`** - the `percent` column is now computed
51
+ as a native Spark column expression instead of a Python UDF.
52
+ Behaviour is identical; performance improves on large datasets.
53
+
54
+ - **`pyspark_.column_into_list()`** - raises `ValueError` (with the
55
+ list of available columns) when the requested column does not exist.
56
+ Previously returned `None` silently.
57
+
58
+ - **`pandas_.print_dataframe_overview()`** - now returns a
59
+ `Dict[str, Dict[str, Any]]` of per-column stats (`unique`,
60
+ `null_count`, `value_counts`). Still prints to stdout as before;
61
+ existing call sites are unaffected.
62
+
63
+ - **`pandas_.compare_dataframes()`** - now returns a comparison
64
+ summary dict (`same_length`, `df1_length`, `df2_length`, `columns`).
65
+ Still prints to stdout as before; existing call sites are unaffected.
66
+
67
+ - **`pyspark_` module** - all `print()` calls replaced with
68
+ `logger.info()` / `logger.debug()`. Output is now routed through
69
+ the standard logging pipeline and can be silenced or redirected.
70
+
71
+ - **`sqlalchemy_.create_sqlalchemy_engine()`** - duplicate
72
+ `if/elif` timeout branches (both setting the same value) consolidated
73
+ into a single condition.
74
+
75
+ - **`django_.django_validate_phone()`** - now has an explicit
76
+ `return None` on failure instead of a bare `return`.
77
+
78
+ ### Fixed (previous pass - reference)
79
+
80
+ - `pyspark_.columns_statistics()` - always-true condition in empty-column
81
+ detection (third clause was truthy for any non-empty string).
82
+ - `pandas_.dtypes_dictionary()` - `.iteritems()` removed in pandas 2.0;
83
+ replaced with `.items()`.
84
+ - Bare `except:` replaced with `except Exception:` in `pandas_` and
85
+ `django_`.
86
+ - `base.string_boolean_to_int()` - removed (used `distutils`, dropped
87
+ in Python 3.12).
88
+ - `flask_.py` - deleted (was entirely commented-out dead code).
89
+ - `beautifulsoup_.preprocess()` - fixed mixed tabs/spaces and invalid
90
+ `\s` escape sequences.
91
+ - All modules now guard third-party imports with `try/except`; the
92
+ package imports cleanly even when optional dependencies are missing.
@@ -23,13 +23,16 @@ include:
23
23
  Examples of unacceptable behavior by participants include:
24
24
 
25
25
  * The use of sexualized language or imagery and unwelcome sexual attention or
26
- advances
26
+
27
+ advances
27
28
  * Trolling, insulting/derogatory comments, and personal or political attacks
28
29
  * Public or private harassment
29
30
  * Publishing others' private information, such as a physical or electronic
30
- address, without explicit permission
31
+
32
+ address, without explicit permission
31
33
  * Other conduct which could reasonably be considered inappropriate in a
32
- professional setting
34
+
35
+ professional setting
33
36
 
34
37
  ## Our Responsibilities
35
38
 
@@ -55,7 +58,7 @@ further defined and clarified by project maintainers.
55
58
  ## Enforcement
56
59
 
57
60
  Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at Shawn.coding.acc@gmail.com. All
61
+ reported by contacting the project team at <Shawn.coding.acc@gmail.com>. All
59
62
  complaints will be reviewed and investigated and will result in a response that
60
63
  is deemed necessary and appropriate to the circumstances. The project team is
61
64
  obligated to maintain confidentiality with regard to the reporter of an incident.
@@ -68,9 +71,9 @@ members of the project's leadership.
68
71
  ## Attribution
69
72
 
70
73
  This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
74
+ available at <https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>
72
75
 
73
76
  [homepage]: https://www.contributor-covenant.org
74
77
 
75
78
  For answers to common questions about this code of conduct, see
76
- https://www.contributor-covenant.org/faq
79
+ <https://www.contributor-covenant.org/faq>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: data_manipulation
3
- Version: 0.50
3
+ Version: 0.54
4
4
  Summary: Powerful data manipulation
5
5
  Author-email: Shawn Ng <shawn.coding.acc@gmail.com>
6
6
  License-Expression: BSD-3-Clause
@@ -10,21 +10,16 @@ Classifier: Environment :: Console
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Intended Audience :: Science/Research
12
12
  Classifier: Programming Language :: Python
13
- Classifier: Programming Language :: Python :: 3.9
14
- Classifier: Programming Language :: Python :: 3.10
15
- Classifier: Programming Language :: Python :: 3.11
16
- Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.14
17
14
  Classifier: Programming Language :: Cython
18
15
  Classifier: Topic :: Scientific/Engineering
19
- Requires-Python: >=3.9
16
+ Requires-Python: >=3.14
20
17
  Description-Content-Type: text/markdown
21
18
  License-File: LICENSE
22
19
  Requires-Dist: beautifulsoup4
23
20
  Requires-Dist: boto3
24
21
  Requires-Dist: cryptography
25
- Requires-Dist: django
26
22
  Requires-Dist: flask
27
- Requires-Dist: geopandas
28
23
  Requires-Dist: ipython
29
24
  Requires-Dist: loguru
30
25
  Requires-Dist: mysql-connector-python
@@ -34,6 +29,9 @@ Requires-Dist: psycopg
34
29
  Requires-Dist: pyspark
35
30
  Requires-Dist: python-dotenv
36
31
  Requires-Dist: sqlalchemy
32
+ Provides-Extra: test
33
+ Requires-Dist: pytest; extra == "test"
34
+ Requires-Dist: pytest-mock; extra == "test"
37
35
  Dynamic: license-file
38
36
 
39
37
  # Data Manipulation
@@ -43,6 +41,7 @@ Dynamic: license-file
43
41
  - [Where to get it](#where-to-get-it)
44
42
  - [Dependencies](#dependencies)
45
43
  - [License](#license)
44
+ - [Maintainer Release](#maintainer-release)
46
45
  - [Getting Help](#getting-help)
47
46
  - [Discussion and Development](#discussion-and-development)
48
47
  - [Contributing to data manipulation](#contributing-to-data-manipulation)
@@ -55,7 +54,7 @@ Data Manipulation is a Python package providing powerful utility functions. It c
55
54
 
56
55
  ## Where to get it
57
56
 
58
- The source code is currently hosted on GitHub at: https://github.com/shawnngtq/data-manipulation
57
+ The source code is currently hosted on GitHub at: <https://github.com/shawnngtq/data-manipulation>
59
58
 
60
59
  ```bash
61
60
  pip install data-manipulation
@@ -69,6 +68,10 @@ The dependencies will be installed automatically along with this package, using
69
68
 
70
69
  [BSD 3](LICENSE)
71
70
 
71
+ ## Maintainer Release
72
+
73
+ Release and deployment steps are documented in [RELEASE.md](RELEASE.md).
74
+
72
75
  ## Getting Help
73
76
 
74
77
  For usage questions, the best place to go to is StackOverflow.
@@ -5,6 +5,7 @@
5
5
  - [Where to get it](#where-to-get-it)
6
6
  - [Dependencies](#dependencies)
7
7
  - [License](#license)
8
+ - [Maintainer Release](#maintainer-release)
8
9
  - [Getting Help](#getting-help)
9
10
  - [Discussion and Development](#discussion-and-development)
10
11
  - [Contributing to data manipulation](#contributing-to-data-manipulation)
@@ -17,7 +18,7 @@ Data Manipulation is a Python package providing powerful utility functions. It c
17
18
 
18
19
  ## Where to get it
19
20
 
20
- The source code is currently hosted on GitHub at: https://github.com/shawnngtq/data-manipulation
21
+ The source code is currently hosted on GitHub at: <https://github.com/shawnngtq/data-manipulation>
21
22
 
22
23
  ```bash
23
24
  pip install data-manipulation
@@ -31,6 +32,10 @@ The dependencies will be installed automatically along with this package, using
31
32
 
32
33
  [BSD 3](LICENSE)
33
34
 
35
+ ## Maintainer Release
36
+
37
+ Release and deployment steps are documented in [RELEASE.md](RELEASE.md).
38
+
34
39
  ## Getting Help
35
40
 
36
41
  For usage questions, the best place to go to is StackOverflow.
@@ -0,0 +1,101 @@
1
+ # Release Guide
2
+
3
+ This guide is for maintainers publishing documentation to GitHub Pages and
4
+ package artifacts to PyPI.
5
+
6
+ ## Preconditions
7
+
8
+ - Work from a clean `master` branch.
9
+ - Release versions are derived from git tags by `setuptools-scm`.
10
+ - Never build or upload release artifacts from a dirty worktree.
11
+ - Keep PyPI credentials out of git.
12
+
13
+ Check the release state:
14
+
15
+ ```bash
16
+ git checkout master
17
+ git pull --ff-only origin master
18
+ git status
19
+ ```
20
+
21
+ `git status` should report no changes before continuing.
22
+
23
+ ## Tag The Release
24
+
25
+ Use the next release version, for example `0.50`:
26
+
27
+ ```bash
28
+ git tag -a 0.50 -m "Release 0.50"
29
+ git push origin master
30
+ git push origin 0.50
31
+ ```
32
+
33
+ The tag must point at the exact commit being released.
34
+
35
+ ## Publish Documentation
36
+
37
+ Both commands require an environment that provides `mkdocs`, `mkdocs-material`, and
38
+ `mkdocstrings-python` (for example a virtualenv, conda env, or pixi shell). Activate that
39
+ environment before running them.
40
+
41
+ Build the MkDocs documentation (local preview only):
42
+
43
+ ```bash
44
+ ./setup.sh create_update_docs
45
+ ```
46
+
47
+ Deploy to GitHub Pages:
48
+
49
+ ```bash
50
+ ./setup.sh deploy_docs
51
+ ```
52
+
53
+ This publishes the contents of `site/` to the `gh-pages` branch.
54
+
55
+ **Note - documentation and PyPI releases are independent.**
56
+
57
+ - **Tags are only for PyPI releases.** `setuptools-scm` derives the package
58
+ version from git tags. Create a tag only when the shipped `data_manipulation/`
59
+ package changes; tooling- or docs-only changes need no tag.
60
+ - **Docs deploy without a tag.** `deploy_docs` publishes current `master` to the
61
+ separate `gh-pages` branch, independent of any tag or PyPI release.
62
+ - **Commit and push doc/source changes to `master` before building.** The site
63
+ renders the working tree, and `create_update_docs` writes only to the
64
+ gitignored `site/` directory - no tracked files change.
65
+ - **When cutting a release, build docs after tagging** so the published site
66
+ matches the released commit.
67
+
68
+ ## Publish To PyPI
69
+
70
+ Build and validate the distribution artifacts:
71
+
72
+ ```bash
73
+ ./setup.sh cleanup
74
+ ```
75
+
76
+ Upload the artifacts:
77
+
78
+ ```bash
79
+ ./setup.sh upload
80
+ ```
81
+
82
+ When prompted by `twine`, enter the PyPI API token. The token should start with
83
+ `pypi-`. It will not be displayed while typing or pasting.
84
+
85
+ ## Verify The Release
86
+
87
+ Install the published package in a fresh environment and confirm the version:
88
+
89
+ ```bash
90
+ python3 -m pip install --upgrade data-manipulation
91
+ python3 -c "import data_manipulation; print(data_manipulation.__version__)"
92
+ ```
93
+
94
+ ## Security Notes
95
+
96
+ - Do not commit PyPI API tokens, passwords, or `.pypirc` files with credentials.
97
+ - Do not add tokens to shell history as command-line arguments.
98
+ - Prefer entering the PyPI token at the `twine` prompt or using a local secret
99
+ store.
100
+ - If a token is accidentally committed or exposed, revoke it in PyPI immediately
101
+ and create a new one.
@@ -0,0 +1,24 @@
1
+ """Repo-root pytest configuration.
2
+
3
+ ``--doctest-modules`` (see ``[tool.pytest.ini_options]``) collects doctests from
4
+ every ``data_manipulation/*.py``. We only want to *execute* examples that are
5
+ robustly runnable, so ignore the rest here. Their ``Examples:`` blocks still
6
+ render in the mkdocs API reference — they are just not auto-verified.
7
+
8
+ Auto-verified modules (not ignored): base.py, beautifulsoup_.py, sqlalchemy_.py.
9
+ """
10
+
11
+ collect_ignore = [
12
+ "data_manipulation/__init__.py",
13
+ "data_manipulation/_version.py",
14
+ "data_manipulation/pandas_.py",
15
+ "data_manipulation/pyspark_.py",
16
+ "data_manipulation/boto3_.py",
17
+ "data_manipulation/kerberos_.py",
18
+ "data_manipulation/openldap_.py",
19
+ "data_manipulation/cryptography_.py",
20
+ "data_manipulation/mysql_connector_python_.py",
21
+ "data_manipulation/postgres_.py",
22
+ "data_manipulation/smtplib_.py",
23
+ "data_manipulation/polars_.py",
24
+ ]
@@ -3,15 +3,11 @@ from data_manipulation import (
3
3
  beautifulsoup_,
4
4
  boto3_,
5
5
  cryptography_,
6
- django_,
7
- flask_,
8
- geopandas_,
9
6
  kerberos_,
10
7
  mysql_connector_python_,
11
8
  openldap_,
12
9
  pandas_,
13
10
  postgres_,
14
- prometheus_,
15
11
  pyspark_,
16
12
  smtplib_,
17
13
  sqlalchemy_,
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.50'
22
- __version_tuple__ = version_tuple = (0, 50)
21
+ __version__ = version = '0.54'
22
+ __version_tuple__ = version_tuple = (0, 54)
23
23
 
24
- __commit_id__ = commit_id = 'g3a0e189a0'
24
+ __commit_id__ = commit_id = 'g7826f58d8'