From 777495ef272eba007819171855151caa2a72a3f0 Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Thu, 8 May 2025 12:49:44 +0200 Subject: [PATCH 01/17] chore: Bump version manually only in pyproject.toml --- .pre-commit-config.yaml | 2 +- docs/installation.md | 8 ++++---- narwhals/__init__.py | 4 +++- tests/version_test.py | 14 ++++++++++++++ utils/bump_version.py | 18 ------------------ utils/check_api_reference.py | 4 +++- 6 files changed, 25 insertions(+), 25 deletions(-) create mode 100644 tests/version_test.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e9219a9130..63986b00c8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,7 +47,7 @@ repos: pass_filenames: false entry: python -m utils.check_api_reference language: python - additional_dependencies: [polars] + additional_dependencies: [., polars] - id: imports-are-banned name: import are banned (use `get_pandas` instead of `import pandas`) entry: python utils/import_check.py diff --git a/docs/installation.md b/docs/installation.md index 47e1e57a3c..d42cca2bc5 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -27,10 +27,10 @@ To verify the installation, start the Python REPL and execute: -```python ->>> import narwhals ->>> narwhals.__version__ -'1.38.1' +```python exec="1" source="above" session="quickstart" result="python" +import narwhals + +print(narwhals.__version__) ``` If you see the version number, then the installation was successful! diff --git a/narwhals/__init__.py b/narwhals/__init__.py index ffc5c40556..c296cfeb8a 100644 --- a/narwhals/__init__.py +++ b/narwhals/__init__.py @@ -1,5 +1,7 @@ from __future__ import annotations +from importlib import metadata + from narwhals import dependencies from narwhals import dtypes from narwhals import exceptions @@ -81,7 +83,7 @@ from narwhals.utils import maybe_reset_index from narwhals.utils import maybe_set_index -__version__ = "1.38.1" +__version__ = metadata.version(__name__) __all__ = [ "Array", diff --git a/tests/version_test.py b/tests/version_test.py new file mode 100644 index 0000000000..1a1cb034e2 --- /dev/null +++ b/tests/version_test.py @@ -0,0 +1,14 @@ +from __future__ import annotations + +import re +from pathlib import Path + +import narwhals as nw + + +def test_version_matches_pyproject() -> None: + with Path("pyproject.toml").open(encoding="utf-8") as file: + content = file.read() + pyproject_version = re.search(r'version = "(.*)"', content).group(1) # type: ignore[union-attr] + + assert nw.__version__ == pyproject_version diff --git a/utils/bump_version.py b/utils/bump_version.py index fe4079d607..a674d7e0d6 100644 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -56,24 +56,6 @@ with open("pyproject.toml", "w", encoding="utf-8") as f: f.write(content) -with open("narwhals/__init__.py", encoding="utf-8") as f: - content = f.read() -content = content.replace( - f'__version__ = "{old_version}"', - f'__version__ = "{version}"', -) -with open("narwhals/__init__.py", "w", encoding="utf-8") as f: - f.write(content) - -with open("docs/installation.md", encoding="utf-8") as f: - content = f.read() -content = content.replace( - f"'{old_version}'", - f"'{version}'", -) -with open("docs/installation.md", "w", encoding="utf-8") as f: - f.write(content) - subprocess.run(["git", "commit", "-a", "-m", f"release: Bump version to {version}"]) subprocess.run(["git", "tag", "-a", f"v{version}", "-m", f"v{version}"]) subprocess.run(["git", "push", "upstream", "HEAD", "--follow-tags"]) diff --git a/utils/check_api_reference.py b/utils/check_api_reference.py index 5954abfd6b..5322b835c4 100644 --- a/utils/check_api_reference.py +++ b/utils/check_api_reference.py @@ -76,7 +76,9 @@ def iter_api_reference_names(tp: type[Any]) -> Iterator[str]: # Top level functions top_level_functions = [ - i for i in dir(nw) if not i[0].isupper() and i[0] != "_" and i not in files + i + for i in dir(nw) + if not i[0].isupper() and i[0] != "_" and i not in files and i != "metadata" ] with open("docs/api-reference/narwhals.md") as fd: content = fd.read() From 8485943779b8ad440cf6f5c027a868e253ceceb3 Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Thu, 8 May 2025 12:55:25 +0200 Subject: [PATCH 02/17] rollback pre-commit --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 63986b00c8..e9219a9130 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,7 +47,7 @@ repos: pass_filenames: false entry: python -m utils.check_api_reference language: python - additional_dependencies: [., polars] + additional_dependencies: [polars] - id: imports-are-banned name: import are banned (use `get_pandas` instead of `import pandas`) entry: python utils/import_check.py From e213fcf5d86addbb9dde19e17b4bfb62474c8b0b Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Thu, 8 May 2025 18:11:29 +0200 Subject: [PATCH 03/17] workaround via makefile --- .pre-commit-config.yaml | 5 ++--- Makefile | 5 +++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e9219a9130..42d6eddb98 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,9 +45,8 @@ repos: - id: check-api-reference name: check-api-reference pass_filenames: false - entry: python -m utils.check_api_reference - language: python - additional_dependencies: [polars] + language: system + entry: make check-api-reference - id: imports-are-banned name: import are banned (use `get_pandas` instead of `import pandas`) entry: python utils/import_check.py diff --git a/Makefile b/Makefile index 5a0feb5f93..2cfabf9a96 100644 --- a/Makefile +++ b/Makefile @@ -24,3 +24,8 @@ typing: ## Run typing checks $(VENV_BIN)/uv pip install -U --pre duckdb $(VENV_BIN)/uv pip install -e . --group typing $(VENV_BIN)/mypy + +.PHONY: check-api-reference +check-api-reference: + $(VENV_BIN)/uv pip install ".[polars]" + $(VENV_BIN)/python utils/check_api_reference.py From ed06050cd57f9740cb6eb62238c2876494cb7f98 Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Thu, 8 May 2025 18:24:09 +0200 Subject: [PATCH 04/17] use uv version bump instead of manual process --- utils/bump_version.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/utils/bump_version.py b/utils/bump_version.py index a674d7e0d6..d66c8219b0 100644 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -7,7 +7,8 @@ out = subprocess.run(["git", "fetch", "upstream", "--tags"]) if out.returncode != 0: print( - "Something went wrong with the release process, please check the Narwhals Wiki and try again." + "Something went wrong with the release process, please check the Narwhals Wiki for " + "at https://github.com/narwhals-dev/narwhals/wiki#release-process and try again." ) print(out) sys.exit(1) @@ -42,19 +43,8 @@ how = sys.argv[1] -with open("pyproject.toml", encoding="utf-8") as f: - content = f.read() -old_version = re.search(r'version = "(.*)"', content).group(1) # pyright: ignore[reportOptionalMemberAccess] -version = old_version.split(".") -if how == "patch": - version = ".".join(version[:-1] + [str(int(version[-1]) + 1)]) -elif how == "minor": - version = ".".join(version[:-2] + [str(int(version[-2]) + 1), "0"]) -elif how == "major": - version = ".".join([str(int(version[0]) + 1), "0", "0"]) -content = content.replace(f'version = "{old_version}"', f'version = "{version}"') -with open("pyproject.toml", "w", encoding="utf-8") as f: - f.write(content) +subprocess.run(["uv", "version", "--bump", how]) +version = subprocess.run(["uv", "version", "--short"], capture_output=True).stdout.decode("utf-8") subprocess.run(["git", "commit", "-a", "-m", f"release: Bump version to {version}"]) subprocess.run(["git", "tag", "-a", f"v{version}", "-m", f"v{version}"]) From a130984946ee55ee3116630d6085bea0e202d52d Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Thu, 8 May 2025 18:59:46 +0200 Subject: [PATCH 05/17] do we have uv? --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2cfabf9a96..15873a98d3 100644 --- a/Makefile +++ b/Makefile @@ -21,11 +21,13 @@ help: ## Display this help screen .PHONY: typing typing: ## Run typing checks # install duckdb nightly so mypy recognises duckdb.SQLExpression + uv venv --allow-existing $(VENV_BIN)/uv pip install -U --pre duckdb $(VENV_BIN)/uv pip install -e . --group typing $(VENV_BIN)/mypy .PHONY: check-api-reference check-api-reference: - $(VENV_BIN)/uv pip install ".[polars]" + uv venv --allow-existing + $(VENV_BIN)/uv pip install -e ".[polars]" $(VENV_BIN)/python utils/check_api_reference.py From 50efe76ca45ff3bb20907288d1d599aacac1fa9f Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Thu, 8 May 2025 19:01:01 +0200 Subject: [PATCH 06/17] install uv to begin with --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 15873a98d3..0556feb9c5 100644 --- a/Makefile +++ b/Makefile @@ -28,6 +28,7 @@ typing: ## Run typing checks .PHONY: check-api-reference check-api-reference: + python -m pip install uv uv venv --allow-existing $(VENV_BIN)/uv pip install -e ".[polars]" $(VENV_BIN)/python utils/check_api_reference.py From 59ea2d2109a7b3896215d450d45d7b3eb31ea20e Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Thu, 8 May 2025 19:06:20 +0200 Subject: [PATCH 07/17] ok easier than expected --- .pre-commit-config.yaml | 5 +++-- Makefile | 8 -------- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 42d6eddb98..eda4691185 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -45,8 +45,9 @@ repos: - id: check-api-reference name: check-api-reference pass_filenames: false - language: system - entry: make check-api-reference + entry: python utils/check_api_reference.py + language: python + additional_dependencies: [narwhals, polars] - id: imports-are-banned name: import are banned (use `get_pandas` instead of `import pandas`) entry: python utils/import_check.py diff --git a/Makefile b/Makefile index 0556feb9c5..5a0feb5f93 100644 --- a/Makefile +++ b/Makefile @@ -21,14 +21,6 @@ help: ## Display this help screen .PHONY: typing typing: ## Run typing checks # install duckdb nightly so mypy recognises duckdb.SQLExpression - uv venv --allow-existing $(VENV_BIN)/uv pip install -U --pre duckdb $(VENV_BIN)/uv pip install -e . --group typing $(VENV_BIN)/mypy - -.PHONY: check-api-reference -check-api-reference: - python -m pip install uv - uv venv --allow-existing - $(VENV_BIN)/uv pip install -e ".[polars]" - $(VENV_BIN)/python utils/check_api_reference.py From 4200ffc5e2e2a939fb1caebc9064096545247b3f Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Thu, 8 May 2025 19:25:38 +0200 Subject: [PATCH 08/17] eureka - add a python env initializer --- .pre-commit-config.yaml | 12 +++++++++--- Makefile | 5 +++++ utils/check_api_reference.py | 4 +--- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index eda4691185..bccc7ab8ce 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,12 +42,18 @@ repos: )$ - repo: local hooks: + - id: init-env + name: init-env + entry: python --version + language: python + pass_filenames: false + description: This hook serves as a env initializer, used both in check-api-reference and mypy hook - id: check-api-reference name: check-api-reference + entry: make check-api-reference + language: system + require_serial: true pass_filenames: false - entry: python utils/check_api_reference.py - language: python - additional_dependencies: [narwhals, polars] - id: imports-are-banned name: import are banned (use `get_pandas` instead of `import pandas`) entry: python utils/import_check.py diff --git a/Makefile b/Makefile index 5a0feb5f93..2cfabf9a96 100644 --- a/Makefile +++ b/Makefile @@ -24,3 +24,8 @@ typing: ## Run typing checks $(VENV_BIN)/uv pip install -U --pre duckdb $(VENV_BIN)/uv pip install -e . --group typing $(VENV_BIN)/mypy + +.PHONY: check-api-reference +check-api-reference: + $(VENV_BIN)/uv pip install ".[polars]" + $(VENV_BIN)/python utils/check_api_reference.py diff --git a/utils/check_api_reference.py b/utils/check_api_reference.py index 5322b835c4..803d6d4e69 100644 --- a/utils/check_api_reference.py +++ b/utils/check_api_reference.py @@ -76,9 +76,7 @@ def iter_api_reference_names(tp: type[Any]) -> Iterator[str]: # Top level functions top_level_functions = [ - i - for i in dir(nw) - if not i[0].isupper() and i[0] != "_" and i not in files and i != "metadata" + i for i in nw.__all__ if not i[0].isupper() and i[0] != "_" and i not in files ] with open("docs/api-reference/narwhals.md") as fd: content = fd.read() From 79d7a89647195801cf71a66c2f43dd280276981f Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Thu, 8 May 2025 22:35:27 +0100 Subject: [PATCH 09/17] chore(ruff): lint --- pyproject.toml | 3 ++- utils/bump_version.py | 34 ++++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 79a35cae82..02859e244a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -124,7 +124,7 @@ exclude = [ line-length = 90 fix = true target-version = "py38" -extend-exclude = ["utils/bump_version.py", "**/this.py"] +extend-exclude = ["**/this.py"] [tool.ruff.lint] preview = true @@ -189,6 +189,7 @@ builtins-ignorelist = ["format"] ] "tpch/tests/*" = ["S101"] "utils/*" = ["S311", "PTH123"] +"utils/bump_version.py" = ["S603", "S607", "T201"] "tpch/execute/*" = ["T201"] "tpch/notebooks/*" = [ "ANN001", diff --git a/utils/bump_version.py b/utils/bump_version.py index d66c8219b0..4b2968901d 100644 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -1,10 +1,10 @@ # mypy: ignore -# ruff: noqa -import re +from __future__ import annotations + import subprocess import sys -out = subprocess.run(["git", "fetch", "upstream", "--tags"]) +out = subprocess.run(["git", "fetch", "upstream", "--tags"], check=False) if out.returncode != 0: print( "Something went wrong with the release process, please check the Narwhals Wiki for " @@ -12,11 +12,11 @@ ) print(out) sys.exit(1) -subprocess.run(["git", "reset", "--hard", "upstream/main"]) +subprocess.run(["git", "reset", "--hard", "upstream/main"], check=False) if ( subprocess.run( - ["git", "branch", "--show-current"], text=True, capture_output=True + ["git", "branch", "--show-current"], text=True, capture_output=True, check=False ).stdout.strip() != "bump-version" ): @@ -38,15 +38,21 @@ except subprocess.CalledProcessError as e: print(f"An error occurred: {e}") -subprocess.run(["git", "fetch", "upstream", "--tags"]) -subprocess.run(["git", "fetch", "upstream", "--prune", "--tags"]) +subprocess.run(["git", "fetch", "upstream", "--tags"], check=False) +subprocess.run(["git", "fetch", "upstream", "--prune", "--tags"], check=False) how = sys.argv[1] -subprocess.run(["uv", "version", "--bump", how]) -version = subprocess.run(["uv", "version", "--short"], capture_output=True).stdout.decode("utf-8") - -subprocess.run(["git", "commit", "-a", "-m", f"release: Bump version to {version}"]) -subprocess.run(["git", "tag", "-a", f"v{version}", "-m", f"v{version}"]) -subprocess.run(["git", "push", "upstream", "HEAD", "--follow-tags"]) -subprocess.run(["git", "push", "upstream", "HEAD:stable", "-f", "--follow-tags"]) +subprocess.run(["uv", "version", "--bump", how], check=False) +version = subprocess.run( + ["uv", "version", "--short"], capture_output=True, text=True, check=False +).stdout + +subprocess.run( + ["git", "commit", "-a", "-m", f"release: Bump version to {version}"], check=False +) +subprocess.run(["git", "tag", "-a", f"v{version}", "-m", f"v{version}"], check=False) +subprocess.run(["git", "push", "upstream", "HEAD", "--follow-tags"], check=False) +subprocess.run( + ["git", "push", "upstream", "HEAD:stable", "-f", "--follow-tags"], check=False +) From 6636d60dc702dba357c8980cbb20f8e5895f8995 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Thu, 8 May 2025 22:47:02 +0100 Subject: [PATCH 10/17] ci: Add some constants --- utils/bump_version.py | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/utils/bump_version.py b/utils/bump_version.py index 4b2968901d..b0ab7c2f3f 100644 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -4,7 +4,17 @@ import subprocess import sys -out = subprocess.run(["git", "fetch", "upstream", "--tags"], check=False) +GIT = "git" +UV = "uv" +FETCH = "fetch" +PUSH = "push" +COMMIT = "commit" +UPSTREAM = "upstream" +TAGS = "--tags" +TAG = "tag" +VERSION = "version" + +out = subprocess.run([GIT, FETCH, UPSTREAM, TAGS], check=False) if out.returncode != 0: print( "Something went wrong with the release process, please check the Narwhals Wiki for " @@ -12,11 +22,11 @@ ) print(out) sys.exit(1) -subprocess.run(["git", "reset", "--hard", "upstream/main"], check=False) +subprocess.run([GIT, "reset", "--hard", "upstream/main"], check=False) if ( subprocess.run( - ["git", "branch", "--show-current"], text=True, capture_output=True, check=False + [GIT, "branch", "--show-current"], text=True, capture_output=True, check=False ).stdout.strip() != "bump-version" ): @@ -26,33 +36,29 @@ # Delete local tags, if present try: # Get the list of all tags - result = subprocess.run( - ["git", "tag", "-l"], capture_output=True, text=True, check=True - ) + result = subprocess.run([GIT, TAG, "-l"], capture_output=True, text=True, check=True) tags = result.stdout.splitlines() # Split the tags into a list by lines # Delete each tag using git tag -d for tag in tags: - subprocess.run(["git", "tag", "-d", tag], check=True) + subprocess.run([GIT, TAG, "-d", tag], check=True) print("All local tags have been deleted.") except subprocess.CalledProcessError as e: print(f"An error occurred: {e}") -subprocess.run(["git", "fetch", "upstream", "--tags"], check=False) -subprocess.run(["git", "fetch", "upstream", "--prune", "--tags"], check=False) +subprocess.run([GIT, FETCH, UPSTREAM, TAGS], check=False) +subprocess.run([GIT, FETCH, UPSTREAM, "--prune", TAGS], check=False) how = sys.argv[1] -subprocess.run(["uv", "version", "--bump", how], check=False) +subprocess.run([UV, VERSION, "--bump", how], check=False) version = subprocess.run( - ["uv", "version", "--short"], capture_output=True, text=True, check=False + [UV, VERSION, "--short"], capture_output=True, text=True, check=False ).stdout subprocess.run( - ["git", "commit", "-a", "-m", f"release: Bump version to {version}"], check=False -) -subprocess.run(["git", "tag", "-a", f"v{version}", "-m", f"v{version}"], check=False) -subprocess.run(["git", "push", "upstream", "HEAD", "--follow-tags"], check=False) -subprocess.run( - ["git", "push", "upstream", "HEAD:stable", "-f", "--follow-tags"], check=False + [GIT, COMMIT, "-a", "-m", f"release: Bump version to {version}"], check=False ) +subprocess.run([GIT, TAG, "-a", f"v{version}", "-m", f"v{version}"], check=False) +subprocess.run([GIT, PUSH, UPSTREAM, "HEAD", "--follow-tags"], check=False) +subprocess.run([GIT, PUSH, UPSTREAM, "HEAD:stable", "-f", "--follow-tags"], check=False) From 8a792210d4d4c718ba37d0899c645ab83bf015c5 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Thu, 8 May 2025 22:49:34 +0100 Subject: [PATCH 11/17] ci: alias `subprocess` to `sp` --- utils/bump_version.py | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/utils/bump_version.py b/utils/bump_version.py index b0ab7c2f3f..ec95126242 100644 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -1,7 +1,7 @@ # mypy: ignore from __future__ import annotations -import subprocess +import subprocess as sp import sys GIT = "git" @@ -14,7 +14,7 @@ TAG = "tag" VERSION = "version" -out = subprocess.run([GIT, FETCH, UPSTREAM, TAGS], check=False) +out = sp.run([GIT, FETCH, UPSTREAM, TAGS], check=False) if out.returncode != 0: print( "Something went wrong with the release process, please check the Narwhals Wiki for " @@ -22,10 +22,10 @@ ) print(out) sys.exit(1) -subprocess.run([GIT, "reset", "--hard", "upstream/main"], check=False) +sp.run([GIT, "reset", "--hard", "upstream/main"], check=False) if ( - subprocess.run( + sp.run( [GIT, "branch", "--show-current"], text=True, capture_output=True, check=False ).stdout.strip() != "bump-version" @@ -36,29 +36,27 @@ # Delete local tags, if present try: # Get the list of all tags - result = subprocess.run([GIT, TAG, "-l"], capture_output=True, text=True, check=True) + result = sp.run([GIT, TAG, "-l"], capture_output=True, text=True, check=True) tags = result.stdout.splitlines() # Split the tags into a list by lines # Delete each tag using git tag -d for tag in tags: - subprocess.run([GIT, TAG, "-d", tag], check=True) + sp.run([GIT, TAG, "-d", tag], check=True) print("All local tags have been deleted.") -except subprocess.CalledProcessError as e: +except sp.CalledProcessError as e: print(f"An error occurred: {e}") -subprocess.run([GIT, FETCH, UPSTREAM, TAGS], check=False) -subprocess.run([GIT, FETCH, UPSTREAM, "--prune", TAGS], check=False) +sp.run([GIT, FETCH, UPSTREAM, TAGS], check=False) +sp.run([GIT, FETCH, UPSTREAM, "--prune", TAGS], check=False) how = sys.argv[1] -subprocess.run([UV, VERSION, "--bump", how], check=False) -version = subprocess.run( +sp.run([UV, VERSION, "--bump", how], check=False) +version = sp.run( [UV, VERSION, "--short"], capture_output=True, text=True, check=False ).stdout -subprocess.run( - [GIT, COMMIT, "-a", "-m", f"release: Bump version to {version}"], check=False -) -subprocess.run([GIT, TAG, "-a", f"v{version}", "-m", f"v{version}"], check=False) -subprocess.run([GIT, PUSH, UPSTREAM, "HEAD", "--follow-tags"], check=False) -subprocess.run([GIT, PUSH, UPSTREAM, "HEAD:stable", "-f", "--follow-tags"], check=False) +sp.run([GIT, COMMIT, "-a", "-m", f"release: Bump version to {version}"], check=False) +sp.run([GIT, TAG, "-a", f"v{version}", "-m", f"v{version}"], check=False) +sp.run([GIT, PUSH, UPSTREAM, "HEAD", "--follow-tags"], check=False) +sp.run([GIT, PUSH, UPSTREAM, "HEAD:stable", "-f", "--follow-tags"], check=False) From 47192aefec80f0385cf3c53d40d09c342bcee0ec Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Fri, 9 May 2025 13:02:32 +0200 Subject: [PATCH 12/17] rollback to avoid using importlib metadata version --- .pre-commit-config.yaml | 12 +++--------- Makefile | 5 ----- narwhals/__init__.py | 4 +--- utils/bump_version.py | 32 +++++++++++++++++++++++++++----- 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bccc7ab8ce..44bebdc700 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,18 +42,12 @@ repos: )$ - repo: local hooks: - - id: init-env - name: init-env - entry: python --version - language: python - pass_filenames: false - description: This hook serves as a env initializer, used both in check-api-reference and mypy hook - id: check-api-reference name: check-api-reference entry: make check-api-reference - language: system - require_serial: true - pass_filenames: false + entry: python -m utils.check_api_reference + language: python + additional_dependencies: [polars] - id: imports-are-banned name: import are banned (use `get_pandas` instead of `import pandas`) entry: python utils/import_check.py diff --git a/Makefile b/Makefile index 2cfabf9a96..5a0feb5f93 100644 --- a/Makefile +++ b/Makefile @@ -24,8 +24,3 @@ typing: ## Run typing checks $(VENV_BIN)/uv pip install -U --pre duckdb $(VENV_BIN)/uv pip install -e . --group typing $(VENV_BIN)/mypy - -.PHONY: check-api-reference -check-api-reference: - $(VENV_BIN)/uv pip install ".[polars]" - $(VENV_BIN)/python utils/check_api_reference.py diff --git a/narwhals/__init__.py b/narwhals/__init__.py index c296cfeb8a..3c11123161 100644 --- a/narwhals/__init__.py +++ b/narwhals/__init__.py @@ -1,7 +1,5 @@ from __future__ import annotations -from importlib import metadata - from narwhals import dependencies from narwhals import dtypes from narwhals import exceptions @@ -83,7 +81,7 @@ from narwhals.utils import maybe_reset_index from narwhals.utils import maybe_set_index -__version__ = metadata.version(__name__) +__version__ = "1.38.2" __all__ = [ "Array", diff --git a/utils/bump_version.py b/utils/bump_version.py index ec95126242..da68cddffd 100644 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -1,6 +1,7 @@ # mypy: ignore from __future__ import annotations +import re import subprocess as sp import sys @@ -51,12 +52,33 @@ how = sys.argv[1] -sp.run([UV, VERSION, "--bump", how], check=False) -version = sp.run( - [UV, VERSION, "--short"], capture_output=True, text=True, check=False +versions = sp.run( + [UV, VERSION, "--bump", how], capture_output=True, text=True, check=False ).stdout +pattern = r"(?P\d+\.\d+\.\d+)\s*=>\s*(?P\d+\.\d+\.\d+)" +match = re.search(pattern, versions) -sp.run([GIT, COMMIT, "-a", "-m", f"release: Bump version to {version}"], check=False) -sp.run([GIT, TAG, "-a", f"v{version}", "-m", f"v{version}"], check=False) +if not match: + print( + "Something went wrong with the release process while parsing versions.\n" + f"`uv version --bump {how}` output is: {versions}" + ) + sys.exit(1) + +old_version, new_version = match.group("old"), match.group("new") + +with open("pyproject.toml", encoding="utf-8") as f: + content = f.read() + +content = content.replace( + f'__version__ = "{old_version}"', + f'__version__ = "{new_version}"', +) + +with open("narwhals/__init__.py", "w", encoding="utf-8") as f: + f.write(content) + +sp.run([GIT, COMMIT, "-a", "-m", f"release: Bump version to {new_version}"], check=False) +sp.run([GIT, TAG, "-a", f"v{new_version}", "-m", f"v{new_version}"], check=False) sp.run([GIT, PUSH, UPSTREAM, "HEAD", "--follow-tags"], check=False) sp.run([GIT, PUSH, UPSTREAM, "HEAD:stable", "-f", "--follow-tags"], check=False) From 798a6dd15a197979939cefe24f7fb974ae0bb518 Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Fri, 9 May 2025 13:03:44 +0200 Subject: [PATCH 13/17] pre-commit typo entry --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 44bebdc700..17e7a7d12d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -44,7 +44,6 @@ repos: hooks: - id: check-api-reference name: check-api-reference - entry: make check-api-reference entry: python -m utils.check_api_reference language: python additional_dependencies: [polars] From 71996c343e8efd1801dcc07067c8091ed60eb9b0 Mon Sep 17 00:00:00 2001 From: dangotbanned <125183946+dangotbanned@users.noreply.github.com> Date: Fri, 9 May 2025 12:38:34 +0100 Subject: [PATCH 14/17] chore(suggestion): Lazy `__version__` Mentioned in (https://github.com/narwhals-dev/narwhals/pull/2514#discussion_r2081481822) I'm guessing the other scripts will need to be updated as well --- narwhals/__init__.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/narwhals/__init__.py b/narwhals/__init__.py index 3c11123161..b4008d460b 100644 --- a/narwhals/__init__.py +++ b/narwhals/__init__.py @@ -1,5 +1,7 @@ from __future__ import annotations +import typing as _t + from narwhals import dependencies from narwhals import dtypes from narwhals import exceptions @@ -81,7 +83,7 @@ from narwhals.utils import maybe_reset_index from narwhals.utils import maybe_set_index -__version__ = "1.38.2" +__version__: str __all__ = [ "Array", @@ -165,3 +167,16 @@ "to_py_scalar", "when", ] + + +def __getattr__(name: _t.Literal["__version__"]) -> str: # type: ignore[misc] + if name == "__version__": + global __version__ # noqa: PLW0603 + + from importlib import metadata + + __version__ = metadata.version(__name__) + return __version__ + else: + msg = f"module {__name__!r} has no attribute {name!r}" + raise AttributeError(msg) From 07f61c5fffddd7a7c1f93ed91b5af79c06b08fe0 Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Fri, 9 May 2025 21:38:48 +0200 Subject: [PATCH 15/17] update bump_version and simplify --- utils/bump_version.py | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/utils/bump_version.py b/utils/bump_version.py index da68cddffd..6cdf6d3b28 100644 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -1,7 +1,6 @@ # mypy: ignore from __future__ import annotations -import re import subprocess as sp import sys @@ -52,31 +51,9 @@ how = sys.argv[1] -versions = sp.run( - [UV, VERSION, "--bump", how], capture_output=True, text=True, check=False +new_version = sp.run( + [UV, VERSION, "--bump", how, "--short"], capture_output=True, text=True, check=False ).stdout -pattern = r"(?P\d+\.\d+\.\d+)\s*=>\s*(?P\d+\.\d+\.\d+)" -match = re.search(pattern, versions) - -if not match: - print( - "Something went wrong with the release process while parsing versions.\n" - f"`uv version --bump {how}` output is: {versions}" - ) - sys.exit(1) - -old_version, new_version = match.group("old"), match.group("new") - -with open("pyproject.toml", encoding="utf-8") as f: - content = f.read() - -content = content.replace( - f'__version__ = "{old_version}"', - f'__version__ = "{new_version}"', -) - -with open("narwhals/__init__.py", "w", encoding="utf-8") as f: - f.write(content) sp.run([GIT, COMMIT, "-a", "-m", f"release: Bump version to {new_version}"], check=False) sp.run([GIT, TAG, "-a", f"v{new_version}", "-m", f"v{new_version}"], check=False) From 205f38aa2dbf9c81bd2a5af0c9af1a03c5d4cd78 Mon Sep 17 00:00:00 2001 From: FBruzzesi Date: Fri, 9 May 2025 22:03:39 +0200 Subject: [PATCH 16/17] simplify tags deletion --- utils/bump_version.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/utils/bump_version.py b/utils/bump_version.py index 6cdf6d3b28..24dd786ab0 100644 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -25,12 +25,11 @@ sp.run([GIT, "reset", "--hard", "upstream/main"], check=False) if ( - sp.run( + current_branch := sp.run( [GIT, "branch", "--show-current"], text=True, capture_output=True, check=False ).stdout.strip() - != "bump-version" -): - msg = "`bump_version.py` should be run from `bump-version` branch" +) != "bump-version": + msg = f"`bump_version.py` should be run from `bump-version` branch instead of `{current_branch}`" raise RuntimeError(msg) # Delete local tags, if present @@ -39,9 +38,10 @@ result = sp.run([GIT, TAG, "-l"], capture_output=True, text=True, check=True) tags = result.stdout.splitlines() # Split the tags into a list by lines - # Delete each tag using git tag -d - for tag in tags: - sp.run([GIT, TAG, "-d", tag], check=True) + if tags: + # Delete each tag using git tag -d + sp.run([GIT, TAG, "-d", *tags], check=True) + print("All local tags have been deleted.") except sp.CalledProcessError as e: print(f"An error occurred: {e}") From 6fba9ba95b931a4b9dd02d19abaab6e8b4706601 Mon Sep 17 00:00:00 2001 From: Francesco Bruzzesi <42817048+FBruzzesi@users.noreply.github.com> Date: Sat, 10 May 2025 00:26:26 +0200 Subject: [PATCH 17/17] Update .pre-commit-config.yaml --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 17e7a7d12d..e9219a9130 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -44,6 +44,7 @@ repos: hooks: - id: check-api-reference name: check-api-reference + pass_filenames: false entry: python -m utils.check_api_reference language: python additional_dependencies: [polars]