diff --git a/README.md b/README.md index 80abd3e..41b4d01 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ It's meant to solve two issues with using polars API extensions: Polugins exposes some standard ways to use API extensions - both for your own and third party packages - and then use this discoverability to also generate type stubs with the added typing from the extensions. -Users can either call `register_namespaces` themselves or import polars through `polugins.polars` instead. +Users can either call `register_namespaces` themselves or import polars through `polugins.polars`. Lint rules can then be used to enforce that nothing is imported from polars outside of these locations. Types are generated with the package `polugins_type_gen`. This creates static type stubs with the extensions added to them. @@ -96,12 +96,6 @@ Namespaces can be registered in three ways: - From entry points - From environment variables -They can also be imported: -- By module path -- As imported module - -but then types cannot be generated for them so the three first methods are recommended. - ### Register from pyproject.toml or polugins.toml In either your `pyproject.toml` or a file called `polugins.toml` put @@ -137,55 +131,6 @@ polugins_lazyframe_my_namespace=my_package.namespaces:MyNamespace Which will register a `LazyFrame` namespace located at `my_package.namespaces` called `MyNamespace` as `my_namespace`. -### From module path -In the `register_namespaces` call: -```python -register_namespaces( - _namespaces={ - '': ":" - }, - ) -``` -Concrete example: -```python -register_namespaces( - lazyframe_namespaces={ - 'my_namespace': "my_package:MyNamespace" - }, - ) -``` - -Which will register a `LazyFrame` namespace located at `my_package.namespaces` called `MyNamespace` as `my_namespace`. - -Note that types cannot be generated for namespaces registered with this method - -### As imported module -In the `register_namespaces` call: -```python -from import - -register_namespaces( - _namespaces={ - '': - }, - ) -``` -Concrete example: -```python -from my_package import MyNamespace - -register_namespaces( - lazyframe_namespaces={ - 'my_namespace': MyNamespace - }, - ) -``` - -Which will register a `LazyFrame` namespace located at `my_package.namespaces` called `MyNamespace` as `my_namespace`. - -Note that types cannot be generated for namespaces registered with this method - - ## Generate types To generate types install the python package `polugins_type_gen` and then run `polugins stubs` to create type stubs at "./typings". @@ -214,35 +159,6 @@ If using another tool than `poetry`, use their equivalent way of exposing endpoi Don't use the `pl.api.register_x` in your package. This will make the extension be registered on import which we specifically want to avoid. -## Kitchen sink - - -```python -from polugins import register_namespaces -import polars as pl -from my_package import MyNamespace - -register_namespaces( - # NOTE: Types can be generated for types registered like this: - load_entrypoints=True # Loads from example-package - load_config=True # Loads from pyproject.toml and polugins.toml - load_env=True # Loads from environment variables - # NOTE: Namespaces can also be registered like below but types are NOT be generated for them - lazyframe_namespaces={ - 'my_namespace': MyNamespace, - 'also_my_namespace': "my_package:AlsoMyNamespace" # Note the `:` to separate module path from object - }, - ) - -# All namespaces are now registered -( - pl.LazyFrame() - .external.some_method() - .my_namespace.some_method() - .also_my_namespace.some_method() -) -``` - ## Implementation diff --git a/polugins/CHANGELOG.md b/polugins/CHANGELOG.md new file mode 100644 index 0000000..e86a055 --- /dev/null +++ b/polugins/CHANGELOG.md @@ -0,0 +1,4 @@ +# Unreleased + +# 0.5.0 +- Remove ability to load extensions inline with module path or module import. diff --git a/polugins/README.md b/polugins/README.md index 24e53a8..82e8d9c 100644 --- a/polugins/README.md +++ b/polugins/README.md @@ -2,4 +2,4 @@ Register API extensions for Polars. -See full information at [Github](https://github.com/StefanBRas/polugins) +See full information at [Github](https://github.com/StefanBRas/polugins). diff --git a/polugins/pyproject.toml b/polugins/pyproject.toml index 4ea3101..9d8f045 100644 --- a/polugins/pyproject.toml +++ b/polugins/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "polugins" -version = "0.4.0" +version = "0.5.0" description = "Plugin system for Polars." authors = ["StefanBRas "] readme = "README.md" diff --git a/polugins/src/polugins/_version.py b/polugins/src/polugins/_version.py index 6a9beea..3d18726 100644 --- a/polugins/src/polugins/_version.py +++ b/polugins/src/polugins/_version.py @@ -1 +1 @@ -__version__ = "0.4.0" +__version__ = "0.5.0" diff --git a/polugins/src/polugins/main.py b/polugins/src/polugins/main.py index 2ac6361..3790446 100644 --- a/polugins/src/polugins/main.py +++ b/polugins/src/polugins/main.py @@ -101,23 +101,11 @@ def _get_namespaces( def register_namespaces( *, - lazyframe_namespaces: NamespaceDict = {}, - dataframe_namespaces: NamespaceDict = {}, - expression_namespaces: NamespaceDict = {}, - series_namespaces: NamespaceDict = {}, load_entrypoints: bool = True, load_config: bool = True, load_env: bool = True, ): - for name, namespace in lazyframe_namespaces.items(): - ExtensionClass.LAZYFRAME.register(name, namespace) - for name, namespace in dataframe_namespaces.items(): - ExtensionClass.DATAFRAME.register(name, namespace) - for name, namespace in expression_namespaces.items(): - ExtensionClass.EXPR.register(name, namespace) - for name, namespace in series_namespaces.items(): - ExtensionClass.SERIES.register(name, namespace) - other_namespaces = _get_namespaces(load_entrypoints, load_config, load_env) - for extension_class, namespaces in other_namespaces.items(): + namespaces = _get_namespaces(load_entrypoints, load_config, load_env) + for extension_class, namespaces in namespaces.items(): for name, namespace in namespaces.items(): extension_class.register(name, namespace) diff --git a/polugins/tests/test_main.py b/polugins/tests/test_main.py index 74793fc..d87d52d 100644 --- a/polugins/tests/test_main.py +++ b/polugins/tests/test_main.py @@ -4,23 +4,6 @@ from polugins.main import register_namespaces -def test_custom(): - ldf = LazyFrame() - from polugins._testing.namespaces import CustomNamespace - - register_namespaces( - lazyframe_namespaces={ - "custom": CustomNamespace, - "custom_path": "polugins._testing.namespaces:CustomNamespaceByPath", - }, - load_entrypoints=False, - load_config=False, - load_env=False, - ) - ldf.custom.custom_method(x=1) - ldf.custom_path.custom_method(x=1) - - def test_external(): ldf = LazyFrame() register_namespaces(load_entrypoints=True, load_config=True, load_env=True) diff --git a/polugins_type_gen/CHANGELOG.md b/polugins_type_gen/CHANGELOG.md new file mode 100644 index 0000000..b4586ab --- /dev/null +++ b/polugins_type_gen/CHANGELOG.md @@ -0,0 +1,5 @@ + +# Unreleased + +# 0.5.0 +- Fixed all stubs, they would accidentally be all the same before. diff --git a/polugins_type_gen/pyproject.toml b/polugins_type_gen/pyproject.toml index dc77c6f..d864ce0 100644 --- a/polugins_type_gen/pyproject.toml +++ b/polugins_type_gen/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "polugins_type_gen" -version = "0.4.0" +version = "0.5.0" description = "Type stub generator Polugins." authors = ["StefanBRas "] readme = "README.md" @@ -14,9 +14,7 @@ polugins = ">=0.2" optional = true [tool.poetry.group.dev.dependencies] -polugins = ">=0.2" # We use it for the scripts/generate_polars_stubs.py pytest = "^7.3.1" -mypy = "1.7.1" # Not sure it's considered Public API what we import, so we fix the version. ruff = "0.1.11" nox = "^2023.4.22" coverage = "^7.2.7" diff --git a/polugins_type_gen/scripts/generate_polars_stubs.py b/polugins_type_gen/scripts/generate_polars_stubs.py index 2909622..c34ad00 100644 --- a/polugins_type_gen/scripts/generate_polars_stubs.py +++ b/polugins_type_gen/scripts/generate_polars_stubs.py @@ -139,13 +139,14 @@ def comparison_section( body += f"## {extension_class}\n{diff_chunk(diff)}" return header + body + def newest_version_not_in(versions: set[version.Version]) -> version.Version: current_versions = get_current_versions() return max(current_versions - versions) def create_pr_body(versions: set[version.Version], tempdir_path: Path): - newest_current_version = newest_version_not_in(versions) + newest_current_version = newest_version_not_in(versions) comparisons = { (version_1, version_2): compare_versions(version_1, version_2, tempdir_path) @@ -159,7 +160,9 @@ def create_pr_body(versions: set[version.Version], tempdir_path: Path): return header + body -def compare_versions(version_1: version.Version, version_2, tempdir_path: Path) -> list[tuple[str, str]]: +def compare_versions( + version_1: version.Version, version_2, tempdir_path: Path +) -> list[tuple[str, str]]: results = [] stub_dir_1 = tempdir_path / "no_docstring" / str(version_1) stub_dir_2 = tempdir_path / "no_docstring" / str(version_2) diff --git a/polugins_type_gen/src/polugins_type_gen/cli.py b/polugins_type_gen/src/polugins_type_gen/cli.py index e26adbc..d7f272f 100644 --- a/polugins_type_gen/src/polugins_type_gen/cli.py +++ b/polugins_type_gen/src/polugins_type_gen/cli.py @@ -32,11 +32,7 @@ def create_stubs(version: str): all_namespaces = _get_namespaces() if all(namespace == {} for namespace in all_namespaces.values()): - msg = ( - "No namespaces found. No types will be generated as this is usually an error." - " Note that only namespaces registered through config, env vars or endpoints" - " can have types genered for them." - ) + msg = "No namespaces found. No types will be generated as this is usually an error." raise NoNamespaceRegisteredException(msg) for extension_class, namespaces in all_namespaces.items(): diff --git a/polugins_type_gen/tests/test_stubs.py b/polugins_type_gen/tests/test_stubs.py new file mode 100644 index 0000000..00177bd --- /dev/null +++ b/polugins_type_gen/tests/test_stubs.py @@ -0,0 +1,15 @@ +from pathlib import Path + +import pytest + +stubs_dir = Path(__file__).parent.parent / Path("src", "polugins_type_gen", "_stubs") +all_stub_files = sorted(p for p in stubs_dir.rglob("*") if p.is_file()) + + +def get_id(p: Path): + return f"{p.parts[-4]}_{p.parts[-1]}" + + +@pytest.mark.parametrize("stub_path", all_stub_files, ids=get_id) +def test_stubs(stub_path: Path): + assert "Incomplete" not in stub_path.read_text()