From 196f05a60164344ebb1c9feab44a0bfe3ab50f10 Mon Sep 17 00:00:00 2001 From: "Edgar R. M" Date: Wed, 24 May 2023 15:21:19 -0600 Subject: [PATCH 01/33] refactor: Use inheritance to construct plugin CLI (#936) * refactor: Use inheritance to construct plugin CLI * Update descriptor to generalize plugin CLIs * Add docs * Rename file --------- Co-authored-by: Ken Payne --- docs/guides/custom-clis.md | 38 ++++ docs/guides/index.md | 1 + pyproject.toml | 5 + singer_sdk/cli/__init__.py | 32 ++++ singer_sdk/configuration/_dict_config.py | 8 +- singer_sdk/helpers/_util.py | 2 +- singer_sdk/mapper_base.py | 107 +++++------ singer_sdk/plugin_base.py | 97 +++++++++- singer_sdk/tap_base.py | 228 +++++++++++++---------- singer_sdk/target_base.py | 97 +++++----- 10 files changed, 392 insertions(+), 223 deletions(-) create mode 100644 docs/guides/custom-clis.md diff --git a/docs/guides/custom-clis.md b/docs/guides/custom-clis.md new file mode 100644 index 000000000..f17cabb5b --- /dev/null +++ b/docs/guides/custom-clis.md @@ -0,0 +1,38 @@ +# Custom CLIs + +## Overview + +By default, packages created with the Singer SDK will have a single command, e.g. `tap-my-source`, which will run the application in a Singer-compatible way. However, you may want to add additional commands to your package. For example, you may want to add a command to initialize the database or platform with certain attributes required by the application to run properly. + +## Adding a custom command + +To add a custom command, you will need to add a new method to your plugin class that returns an instance of [`click.Command`](https://click.palletsprojects.com/en/8.1.x/api/#commands) (or a subclass of it) and decorate it with the `singer_sdk.cli.plugin_cli` decorator. Then you will need to add the command to the `[tool.poetry.scripts]` section of your `pyproject.toml` file. + +```python +# tap_shortcut/tap.py + +class ShortcutTap(Tap): + """Shortcut tap class.""" + + @plugin_cli + def update_schema(cls) -> click.Command: + """Update the OpenAPI schema for this tap.""" + @click.command() + def update(): + response = requests.get( + "https://developer.shortcut.com/api/rest/v3/shortcut.swagger.json", + timeout=5, + ) + with Path("tap_shortcut/openapi.json").open("w") as f: + f.write(response.text) + + return update +``` + +```toml +# pyproject.toml + +[tool.poetry.scripts] +tap-shortcut = "tap_shortcut.tap:ShortcutTap.cli" +tap-shortcut-update-schema = "tap_shortcut.tap:ShortcutTap.update_schema" +``` diff --git a/docs/guides/index.md b/docs/guides/index.md index c4f5f8d69..e86aa149c 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -7,4 +7,5 @@ The following pages contain useful information for developers building on top of porting pagination-classes +custom-clis ``` diff --git a/pyproject.toml b/pyproject.toml index 0eeb20e1f..6f047d847 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -306,6 +306,11 @@ parametrize-names-type = "csv" known-first-party = ["singer_sdk", "samples", "tests"] required-imports = ["from __future__ import annotations"] +[tool.ruff.pep8-naming] +classmethod-decorators = [ + "singer_sdk.cli.plugin_cli", +] + [tool.ruff.pydocstyle] convention = "google" diff --git a/singer_sdk/cli/__init__.py b/singer_sdk/cli/__init__.py index 76b58f748..cb0d72607 100644 --- a/singer_sdk/cli/__init__.py +++ b/singer_sdk/cli/__init__.py @@ -1,3 +1,35 @@ """Helpers for the tap, target and mapper CLIs.""" from __future__ import annotations + +import typing as t + +if t.TYPE_CHECKING: + import click + +_T = t.TypeVar("_T") + + +class plugin_cli: # noqa: N801 + """Decorator to create a plugin CLI.""" + + def __init__(self, method: t.Callable[..., click.Command]) -> None: + """Create a new plugin CLI. + + Args: + method: The method to call to get the command. + """ + self.method = method + self.name: str | None = None + + def __get__(self, instance: _T, owner: type[_T]) -> click.Command: + """Get the command. + + Args: + instance: The instance of the plugin. + owner: The plugin class. + + Returns: + The CLI entrypoint. + """ + return self.method(owner) diff --git a/singer_sdk/configuration/_dict_config.py b/singer_sdk/configuration/_dict_config.py index 021099adb..fd8217f01 100644 --- a/singer_sdk/configuration/_dict_config.py +++ b/singer_sdk/configuration/_dict_config.py @@ -85,13 +85,15 @@ def merge_config_sources( A single configuration dictionary. """ config: dict[str, t.Any] = {} - for config_path in inputs: - if config_path == "ENV": + for config_input in inputs: + if config_input == "ENV": env_config = parse_environment_config(config_schema, prefix=env_prefix) config.update(env_config) continue - if not Path(config_path).is_file(): + config_path = Path(config_input) + + if not config_path.is_file(): msg = ( f"Could not locate config file at '{config_path}'.Please check that " "the file exists." diff --git a/singer_sdk/helpers/_util.py b/singer_sdk/helpers/_util.py index 0e1399043..d0079c40d 100644 --- a/singer_sdk/helpers/_util.py +++ b/singer_sdk/helpers/_util.py @@ -10,7 +10,7 @@ def read_json_file(path: PurePath | str) -> dict[str, t.Any]: - """Read json file, thowing an error if missing.""" + """Read json file, throwing an error if missing.""" if not path: msg = "Could not open file. Filepath not provided." raise RuntimeError(msg) diff --git a/singer_sdk/mapper_base.py b/singer_sdk/mapper_base.py index 977da61ea..b0be198bd 100644 --- a/singer_sdk/mapper_base.py +++ b/singer_sdk/mapper_base.py @@ -8,15 +8,11 @@ import click import singer_sdk._singerlib as singer -from singer_sdk.cli import common_options from singer_sdk.helpers._classproperty import classproperty from singer_sdk.helpers.capabilities import CapabilitiesEnum, PluginCapabilities from singer_sdk.io_base import SingerReader from singer_sdk.plugin_base import PluginBase -if t.TYPE_CHECKING: - from io import FileIO - class InlineMapper(PluginBase, SingerReader, metaclass=abc.ABCMeta): """Abstract base class for inline mappers.""" @@ -106,65 +102,54 @@ def map_batch_message( msg = "BATCH messages are not supported by mappers." raise NotImplementedError(msg) - @classproperty - def cli(cls) -> t.Callable: # noqa: N805 + # CLI handler + + @classmethod + def invoke( # type: ignore[override] + cls: type[InlineMapper], + *, + about: bool = False, + about_format: str | None = None, + config: tuple[str, ...] = (), + file_input: t.IO[str] | None = None, + ) -> None: + """Invoke the mapper. + + Args: + about: Display package metadata and settings. + about_format: Specify output style for `--about`. + config: Configuration file location or 'ENV' to use environment + variables. Accepts multiple inputs as a tuple. + file_input: Optional file to read input from. + """ + super().invoke(about=about, about_format=about_format) + cls.print_version(print_fn=cls.logger.info) + config_files, parse_env_config = cls.config_from_cli_args(*config) + + mapper = cls( + config=config_files, # type: ignore[arg-type] + validate_config=True, + parse_env_config=parse_env_config, + ) + mapper.listen(file_input) + + @classmethod + def get_singer_command(cls: type[InlineMapper]) -> click.Command: """Execute standard CLI handler for inline mappers. Returns: - A callable CLI object. + A click.Command object. """ - - @common_options.PLUGIN_VERSION - @common_options.PLUGIN_ABOUT - @common_options.PLUGIN_ABOUT_FORMAT - @common_options.PLUGIN_CONFIG - @common_options.PLUGIN_FILE_INPUT - @click.command( - help="Execute the Singer mapper.", - context_settings={"help_option_names": ["--help"]}, + command = super().get_singer_command() + command.help = "Execute the Singer mapper." + command.params.extend( + [ + click.Option( + ["--input", "file_input"], + help="A path to read messages from instead of from standard in.", + type=click.File("r"), + ), + ], ) - def cli( - *, - version: bool = False, - about: bool = False, - config: tuple[str, ...] = (), - about_format: str | None = None, - file_input: FileIO | None = None, - ) -> None: - """Handle command line execution. - - Args: - version: Display the package version. - about: Display package metadata and settings. - about_format: Specify output style for `--about`. - config: Configuration file location or 'ENV' to use environment - variables. Accepts multiple inputs as a tuple. - file_input: Specify a path to an input file to read messages from. - Defaults to standard in if unspecified. - """ - if version: - cls.print_version() - return - - if not about: - cls.print_version(print_fn=cls.logger.info) - - validate_config: bool = True - if about: - validate_config = False - - cls.print_version(print_fn=cls.logger.info) - - config_files, parse_env_config = cls.config_from_cli_args(*config) - mapper = cls( # type: ignore[operator] - config=config_files or None, - validate_config=validate_config, - parse_env_config=parse_env_config, - ) - - if about: - mapper.print_about(about_format) - else: - mapper.listen(file_input) - - return cli + + return command diff --git a/singer_sdk/plugin_base.py b/singer_sdk/plugin_base.py index 042ee5b54..57a14fe95 100644 --- a/singer_sdk/plugin_base.py +++ b/singer_sdk/plugin_base.py @@ -5,6 +5,7 @@ import abc import logging import os +import sys import typing as t from pathlib import Path, PurePath from types import MappingProxyType @@ -13,6 +14,7 @@ from jsonschema import Draft7Validator from singer_sdk import about, metrics +from singer_sdk.cli import plugin_cli from singer_sdk.configuration._dict_config import ( merge_missing_config_jsonschema, parse_environment_config, @@ -399,16 +401,99 @@ def config_from_cli_args(*args: str) -> tuple[list[Path], bool]: return config_files, parse_env_config - @classproperty - def cli(cls) -> t.Callable: # noqa: N805 + @classmethod + def invoke( + cls, + *, + about: bool = False, + about_format: str | None = None, + **kwargs: t.Any, # noqa: ARG003 + ) -> None: + """Invoke the plugin. + + Args: + about: Display package metadata and settings. + about_format: Specify output style for `--about`. + kwargs: Plugin keyword arguments. + """ + if about: + cls.print_about(about_format) + sys.exit(0) + + @classmethod + def cb_version( + cls: type[PluginBase], + ctx: click.Context, + param: click.Option, # noqa: ARG003 + value: bool, # noqa: FBT001 + ) -> None: + """CLI callback to print the plugin version and exit. + + Args: + ctx: Click context. + param: Click parameter. + value: Boolean indicating whether to print the version. + """ + if not value: + return + cls.print_version(print_fn=click.echo) + ctx.exit() + + @classmethod + def get_singer_command(cls: type[PluginBase]) -> click.Command: """Handle command line execution. Returns: A callable CLI object. """ + return click.Command( + name=cls.name, + callback=cls.invoke, + context_settings={"help_option_names": ["--help"]}, + params=[ + click.Option( + ["--version"], + is_flag=True, + help="Display the package version.", + is_eager=True, + expose_value=False, + callback=cls.cb_version, + ), + click.Option( + ["--about"], + help="Display package metadata and settings.", + is_flag=True, + is_eager=False, + expose_value=True, + ), + click.Option( + ["--format", "about_format"], + help="Specify output style for --about", + type=click.Choice( + ["json", "markdown"], + case_sensitive=False, + ), + default=None, + ), + click.Option( + ["--config"], + multiple=True, + help=( + "Configuration file location or 'ENV' to use environment " + "variables." + ), + type=click.STRING, + default=(), + is_eager=True, + ), + ], + ) - @click.command() - def cli() -> None: - pass + @plugin_cli + def cli(cls) -> click.Command: + """Handle command line execution. - return cli + Returns: + A callable CLI object. + """ + return cls.get_singer_command() diff --git a/singer_sdk/tap_base.py b/singer_sdk/tap_base.py index fb6443a60..e6d999a02 100644 --- a/singer_sdk/tap_base.py +++ b/singer_sdk/tap_base.py @@ -12,7 +12,6 @@ import click from singer_sdk._singerlib import Catalog -from singer_sdk.cli import common_options from singer_sdk.configuration._dict_config import merge_missing_config_jsonschema from singer_sdk.exceptions import AbortedSyncFailedException, AbortedSyncPausedException from singer_sdk.helpers import _state @@ -42,7 +41,7 @@ class CliTestOptionValue(Enum): All = "all" Schema = "schema" - Disabled = False + Disabled = "disabled" class Tap(PluginBase, metaclass=abc.ABCMeta): @@ -459,108 +458,143 @@ def sync_all(self) -> None: # Command Line Execution - @classproperty - def cli(cls) -> t.Callable: # noqa: N805 - """Execute standard CLI handler for taps. + @classmethod + def invoke( # type: ignore[override] + cls: type[Tap], + *, + about: bool = False, + about_format: str | None = None, + config: tuple[str, ...] = (), + state: str | None = None, + catalog: str | None = None, + ) -> None: + """Invoke the tap's command line interface. - Returns: - A callable CLI object. + Args: + about: Display package metadata and settings. + about_format: Specify output style for `--about`. + config: Configuration file location or 'ENV' to use environment + variables. Accepts multiple inputs as a tuple. + catalog: Use a Singer catalog file with the tap.", + state: Use a bookmarks file for incremental replication. """ + super().invoke(about=about, about_format=about_format) + cls.print_version(print_fn=cls.logger.info) + config_files, parse_env_config = cls.config_from_cli_args(*config) - @common_options.PLUGIN_VERSION - @common_options.PLUGIN_ABOUT - @common_options.PLUGIN_ABOUT_FORMAT - @common_options.PLUGIN_CONFIG - @click.option( - "--discover", - is_flag=True, - help="Run the tap in discovery mode.", - ) - @click.option( - "--test", - is_flag=False, - flag_value=CliTestOptionValue.All.value, - default=CliTestOptionValue.Disabled, - help=( - "Use --test to sync a single record for each stream. " - "Use --test=schema to test schema output without syncing " - "records." - ), + tap = cls( + config=config_files, # type: ignore[arg-type] + state=state, + catalog=catalog, + parse_env_config=parse_env_config, + validate_config=True, ) - @click.option( - "--catalog", - help="Use a Singer catalog file with the tap.", - type=click.Path(), + tap.sync_all() + + @classmethod + def cb_discover( + cls: type[Tap], + ctx: click.Context, + param: click.Option, # noqa: ARG003 + value: bool, # noqa: FBT001 + ) -> None: + """CLI callback to run the tap in discovery mode. + + Args: + ctx: Click context. + param: Click option. + value: Whether to run in discovery mode. + """ + if not value: + return + + config_args = ctx.params.get("config", ()) + config_files, parse_env_config = cls.config_from_cli_args(*config_args) + tap = cls( + config=config_files, # type: ignore[arg-type] + parse_env_config=parse_env_config, + validate_config=False, ) - @click.option( - "--state", - help="Use a bookmarks file for incremental replication.", - type=click.Path(), + tap.run_discovery() + ctx.exit() + + @classmethod + def cb_test( + cls: type[Tap], + ctx: click.Context, + param: click.Option, # noqa: ARG003 + value: bool, # noqa: FBT001 + ) -> None: + """CLI callback to run the tap in test mode. + + Args: + ctx: Click context. + param: Click option. + value: Whether to run in test mode. + """ + if value == CliTestOptionValue.Disabled.value: + return + + config_args = ctx.params.get("config", ()) + config_files, parse_env_config = cls.config_from_cli_args(*config_args) + tap = cls( + config=config_files, # type: ignore[arg-type] + parse_env_config=parse_env_config, + validate_config=True, ) - @click.command( - help="Execute the Singer tap.", - context_settings={"help_option_names": ["--help"]}, + + if value == CliTestOptionValue.Schema.value: + tap.write_schemas() + else: + tap.run_connection_test() + + ctx.exit() + + @classmethod + def get_singer_command(cls: type[Tap]) -> click.Command: + """Execute standard CLI handler for taps. + + Returns: + A click.Command object. + """ + command = super().get_singer_command() + command.help = "Execute the Singer tap." + command.params.extend( + [ + click.Option( + ["--discover"], + is_flag=True, + help="Run the tap in discovery mode.", + callback=cls.cb_discover, + expose_value=False, + ), + click.Option( + ["--test"], + is_flag=False, + flag_value=CliTestOptionValue.All.value, + default=CliTestOptionValue.Disabled.value, + help=( + "Use --test to sync a single record for each stream. " + "Use --test=schema to test schema output without syncing " + "records." + ), + callback=cls.cb_test, + expose_value=False, + ), + click.Option( + ["--catalog"], + help="Use a Singer catalog file with the tap.", + type=click.Path(), + ), + click.Option( + ["--state"], + help="Use a bookmarks file for incremental replication.", + type=click.Path(), + ), + ], ) - def cli( - *, - version: bool = False, - about: bool = False, - discover: bool = False, - test: CliTestOptionValue = CliTestOptionValue.Disabled, - config: tuple[str, ...] = (), - state: str | None = None, - catalog: str | None = None, - about_format: str | None = None, - ) -> None: - """Handle command line execution. - - Args: - version: Display the package version. - about: Display package metadata and settings. - discover: Run the tap in discovery mode. - test: Test connectivity by syncing a single record and exiting. - about_format: Specify output style for `--about`. - config: Configuration file location or 'ENV' to use environment - variables. Accepts multiple inputs as a tuple. - catalog: Use a Singer catalog file with the tap.", - state: Use a bookmarks file for incremental replication. - """ - if version: - cls.print_version() - return - - if not about: - cls.print_version(print_fn=cls.logger.info) - else: - cls.print_about(output_format=about_format) - return - - validate_config: bool = True - if discover: - # Don't abort on validation failures - validate_config = False - - config_files, parse_env_config = cls.config_from_cli_args(*config) - tap = cls( # type: ignore[operator] - config=config_files or None, - state=state, - catalog=catalog, - parse_env_config=parse_env_config, - validate_config=validate_config, - ) - - if discover: - tap.run_discovery() - if test == CliTestOptionValue.All.value: - tap.run_connection_test() - elif test == CliTestOptionValue.All.value: - tap.run_connection_test() - elif test == CliTestOptionValue.Schema.value: - tap.write_schemas() - else: - tap.sync_all() - - return cli + + return command class SQLTap(Tap): diff --git a/singer_sdk/target_base.py b/singer_sdk/target_base.py index d44305d67..2fcb28314 100644 --- a/singer_sdk/target_base.py +++ b/singer_sdk/target_base.py @@ -12,7 +12,6 @@ import click from joblib import Parallel, delayed, parallel_backend -from singer_sdk.cli import common_options from singer_sdk.exceptions import RecordsWithoutSchemaException from singer_sdk.helpers._batch import BaseBatchFileEncoding from singer_sdk.helpers._classproperty import classproperty @@ -28,7 +27,6 @@ from singer_sdk.plugin_base import PluginBase if t.TYPE_CHECKING: - from io import FileIO from pathlib import PurePath from singer_sdk.sinks import Sink @@ -518,66 +516,55 @@ def _write_state_message(self, state: dict) -> None: # CLI handler - @classproperty - def cli(cls) -> t.Callable: # noqa: N805 - """Execute standard CLI handler for taps. + @classmethod + def invoke( # type: ignore[override] + cls: type[Target], + *, + about: bool = False, + about_format: str | None = None, + config: tuple[str, ...] = (), + file_input: t.IO[str] | None = None, + ) -> None: + """Invoke the target. - Returns: - A callable CLI object. + Args: + about: Display package metadata and settings. + about_format: Specify output style for `--about`. + config: Configuration file location or 'ENV' to use environment + variables. Accepts multiple inputs as a tuple. + file_input: Optional file to read input from. """ + super().invoke(about=about, about_format=about_format) + cls.print_version(print_fn=cls.logger.info) + config_files, parse_env_config = cls.config_from_cli_args(*config) - @common_options.PLUGIN_VERSION - @common_options.PLUGIN_ABOUT - @common_options.PLUGIN_ABOUT_FORMAT - @common_options.PLUGIN_CONFIG - @common_options.PLUGIN_FILE_INPUT - @click.command( - help="Execute the Singer target.", - context_settings={"help_option_names": ["--help"]}, + target = cls( + config=config_files, # type: ignore[arg-type] + validate_config=True, + parse_env_config=parse_env_config, ) - def cli( - *, - version: bool = False, - about: bool = False, - config: tuple[str, ...] = (), - about_format: str | None = None, - file_input: FileIO | None = None, - ) -> None: - """Handle command line execution. - - Args: - version: Display the package version. - about: Display package metadata and settings. - about_format: Specify output style for `--about`. - config: Configuration file location or 'ENV' to use environment - variables. Accepts multiple inputs as a tuple. - file_input: Specify a path to an input file to read messages from. - Defaults to standard in if unspecified. - """ - if version: - cls.print_version() - return - - if not about: - cls.print_version(print_fn=cls.logger.info) - else: - cls.print_about(output_format=about_format) - return + target.listen(file_input) - validate_config: bool = True - - cls.print_version(print_fn=cls.logger.info) - - config_files, parse_env_config = cls.config_from_cli_args(*config) - target = cls( # type: ignore[operator] - config=config_files or None, - parse_env_config=parse_env_config, - validate_config=validate_config, - ) + @classmethod + def get_singer_command(cls: type[Target]) -> click.Command: + """Execute standard CLI handler for taps. - target.listen(file_input) + Returns: + A click.Command object. + """ + command = super().get_singer_command() + command.help = "Execute the Singer target." + command.params.extend( + [ + click.Option( + ["--input", "file_input"], + help="A path to read messages from instead of from standard in.", + type=click.File("r"), + ), + ], + ) - return cli + return command class SQLTarget(Target): From e729e0ef2f2c715c1106b42d8e855e4c7609cfc8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 14:30:04 +0000 Subject: [PATCH 02/33] chore(deps): Bump actions/setup-python from 4.6.0 to 4.6.1 (#1735) --- .github/workflows/cookiecutter-e2e.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 6 +++--- .github/workflows/version_bump.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cookiecutter-e2e.yml b/.github/workflows/cookiecutter-e2e.yml index 447bb59aa..766857ac0 100644 --- a/.github/workflows/cookiecutter-e2e.yml +++ b/.github/workflows/cookiecutter-e2e.yml @@ -43,7 +43,7 @@ jobs: poetry --version - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: ${{ matrix.python-version }} architecture: x64 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8fb3bcbb2..35d1db076 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@v3.5.2 - name: Set up Python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: "3.10" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2bb693ad8..ed83c627f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -43,7 +43,7 @@ jobs: poetry --version - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: ${{ matrix.python-version }} architecture: x64 @@ -101,7 +101,7 @@ jobs: poetry --version - name: Setup Python 3.10 - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: '3.10' architecture: x64 @@ -141,7 +141,7 @@ jobs: poetry --version - name: Set up Python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: '3.10' cache: 'pip' diff --git a/.github/workflows/version_bump.yml b/.github/workflows/version_bump.yml index 2c40b44b6..1889fcf22 100644 --- a/.github/workflows/version_bump.yml +++ b/.github/workflows/version_bump.yml @@ -40,7 +40,7 @@ jobs: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4.6.0 + uses: actions/setup-python@v4.6.1 with: python-version: "3.10" architecture: x64 From c644bb967cd63abe799c2e4dd2e10b5d11aa6959 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 29 May 2023 21:22:36 -0600 Subject: [PATCH 03/33] chore: pre-commit autoupdate (#1736) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/charliermarsh/ruff-pre-commit: v0.0.269 → v0.0.270](https://github.com/charliermarsh/ruff-pre-commit/compare/v0.0.269...v0.0.270) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .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 76d12e95e..8d308ac62 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,7 +43,7 @@ repos: - id: check-readthedocs - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.269 + rev: v0.0.270 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 535766dbe9222c84322aa02f307b311cc52b72a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 13:07:33 +0000 Subject: [PATCH 04/33] chore(deps): Bump poetry from 1.5.0 to 1.5.1 in /.github/workflows (#1737) --- .github/workflows/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt index d700ee9a9..6596d2c0e 100644 --- a/.github/workflows/constraints.txt +++ b/.github/workflows/constraints.txt @@ -1,5 +1,5 @@ pip==23.1.2 -poetry==1.5.0 +poetry==1.5.1 pre-commit==3.3.2 nox==2023.4.22 nox-poetry==1.0.2 From 40db18a53475139874a2fe8fbb5400117d42de35 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 13:33:50 +0000 Subject: [PATCH 05/33] chore(deps-dev): Bump types-requests from 2.31.0.0 to 2.31.0.1 (#1739) --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4db177b13..cc8bdf883 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2610,14 +2610,14 @@ files = [ [[package]] name = "types-requests" -version = "2.31.0.0" +version = "2.31.0.1" description = "Typing stubs for requests" category = "dev" optional = false python-versions = "*" files = [ - {file = "types-requests-2.31.0.0.tar.gz", hash = "sha256:c1c29d20ab8d84dff468d7febfe8e0cb0b4664543221b386605e14672b44ea25"}, - {file = "types_requests-2.31.0.0-py3-none-any.whl", hash = "sha256:7c5cea7940f8e92ec560bbc468f65bf684aa3dcf0554a6f8c4710f5f708dc598"}, + {file = "types-requests-2.31.0.1.tar.gz", hash = "sha256:3de667cffa123ce698591de0ad7db034a5317457a596eb0b4944e5a9d9e8d1ac"}, + {file = "types_requests-2.31.0.1-py3-none-any.whl", hash = "sha256:afb06ef8f25ba83d59a1d424bd7a5a939082f94b94e90ab5e6116bd2559deaa3"}, ] [package.dependencies] From 03dff2e651c92fa393b24b392fadb43ff44945b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 13:43:56 +0000 Subject: [PATCH 06/33] chore(deps-dev): Bump coverage from 7.2.6 to 7.2.7 (#1740) --- poetry.lock | 113 ++++++++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 52 deletions(-) diff --git a/poetry.lock b/poetry.lock index cc8bdf883..438fe9922 100644 --- a/poetry.lock +++ b/poetry.lock @@ -515,63 +515,72 @@ requests = ">=2.23.0" [[package]] name = "coverage" -version = "7.2.6" +version = "7.2.7" description = "Code coverage measurement for Python" category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "coverage-7.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:496b86f1fc9c81a1cd53d8842ef712e950a4611bba0c42d33366a7b91ba969ec"}, - {file = "coverage-7.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fbe6e8c0a9a7193ba10ee52977d4d5e7652957c1f56ccefed0701db8801a2a3b"}, - {file = "coverage-7.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d06b721c2550c01a60e5d3093f417168658fb454e5dfd9a23570e9bffe39a1"}, - {file = "coverage-7.2.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77a04b84d01f0e12c66f16e69e92616442dc675bbe51b90bfb074b1e5d1c7fbd"}, - {file = "coverage-7.2.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35db06450272473eab4449e9c2ad9bc6a0a68dab8e81a0eae6b50d9c2838767e"}, - {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6727a0d929ff0028b1ed8b3e7f8701670b1d7032f219110b55476bb60c390bfb"}, - {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aac1d5fdc5378f6bac2c0c7ebe7635a6809f5b4376f6cf5d43243c1917a67087"}, - {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1c9e4a5eb1bbc3675ee57bc31f8eea4cd7fb0cbcbe4912cf1cb2bf3b754f4a80"}, - {file = "coverage-7.2.6-cp310-cp310-win32.whl", hash = "sha256:71f739f97f5f80627f1fee2331e63261355fd1e9a9cce0016394b6707ac3f4ec"}, - {file = "coverage-7.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:fde5c7a9d9864d3e07992f66767a9817f24324f354caa3d8129735a3dc74f126"}, - {file = "coverage-7.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc7b667f8654376e9353dd93e55e12ce2a59fb6d8e29fce40de682273425e044"}, - {file = "coverage-7.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:697f4742aa3f26c107ddcb2b1784a74fe40180014edbd9adaa574eac0529914c"}, - {file = "coverage-7.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:541280dde49ce74a4262c5e395b48ea1207e78454788887118c421cb4ffbfcac"}, - {file = "coverage-7.2.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e7f1a8328eeec34c54f1d5968a708b50fc38d31e62ca8b0560e84a968fbf9a9"}, - {file = "coverage-7.2.6-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bbd58eb5a2371bf160590f4262109f66b6043b0b991930693134cb617bc0169"}, - {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ae82c5f168d2a39a5d69a12a69d4dc23837a43cf2ca99be60dfe59996ea6b113"}, - {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f5440cdaf3099e7ab17a5a7065aed59aff8c8b079597b61c1f8be6f32fe60636"}, - {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a6f03f87fea579d55e0b690d28f5042ec1368650466520fbc400e7aeaf09e995"}, - {file = "coverage-7.2.6-cp311-cp311-win32.whl", hash = "sha256:dc4d5187ef4d53e0d4c8eaf530233685667844c5fb0b855fea71ae659017854b"}, - {file = "coverage-7.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:c93d52c3dc7b9c65e39473704988602300e3cc1bad08b5ab5b03ca98bbbc68c1"}, - {file = "coverage-7.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:42c692b55a647a832025a4c048007034fe77b162b566ad537ce65ad824b12a84"}, - {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7786b2fa7809bf835f830779ad285215a04da76293164bb6745796873f0942d"}, - {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25bad4196104761bc26b1dae9b57383826542ec689ff0042f7f4f4dd7a815cba"}, - {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2692306d3d4cb32d2cceed1e47cebd6b1d2565c993d6d2eda8e6e6adf53301e6"}, - {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:392154d09bd4473b9d11351ab5d63391f3d5d24d752f27b3be7498b0ee2b5226"}, - {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fa079995432037b5e2ef5ddbb270bcd2ded9f52b8e191a5de11fe59a00ea30d8"}, - {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d712cefff15c712329113b01088ba71bbcef0f7ea58478ca0bbec63a824844cb"}, - {file = "coverage-7.2.6-cp37-cp37m-win32.whl", hash = "sha256:004948e296149644d208964300cb3d98affc5211e9e490e9979af4030b0d6473"}, - {file = "coverage-7.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:c1d7a31603c3483ac49c1726723b0934f88f2c011c660e6471e7bd735c2fa110"}, - {file = "coverage-7.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3436927d1794fa6763b89b60c896f9e3bd53212001026ebc9080d23f0c2733c1"}, - {file = "coverage-7.2.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44c9b9f1a245f3d0d202b1a8fa666a80b5ecbe4ad5d0859c0fb16a52d9763224"}, - {file = "coverage-7.2.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e3783a286d5a93a2921396d50ce45a909aa8f13eee964465012f110f0cbb611"}, - {file = "coverage-7.2.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cff6980fe7100242170092bb40d2b1cdad79502cd532fd26b12a2b8a5f9aee0"}, - {file = "coverage-7.2.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c534431153caffc7c495c3eddf7e6a6033e7f81d78385b4e41611b51e8870446"}, - {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3062fd5c62df988cea9f2972c593f77fed1182bfddc5a3b12b1e606cb7aba99e"}, - {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6284a2005e4f8061c58c814b1600ad0074ccb0289fe61ea709655c5969877b70"}, - {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:97729e6828643f168a2a3f07848e1b1b94a366b13a9f5aba5484c2215724edc8"}, - {file = "coverage-7.2.6-cp38-cp38-win32.whl", hash = "sha256:dc11b42fa61ff1e788dd095726a0aed6aad9c03d5c5984b54cb9e1e67b276aa5"}, - {file = "coverage-7.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:cbcc874f454ee51f158afd604a315f30c0e31dff1d5d5bf499fc529229d964dd"}, - {file = "coverage-7.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d3cacc6a665221108ecdf90517a8028d07a2783df3417d12dcfef1c517e67478"}, - {file = "coverage-7.2.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:272ab31228a9df857ab5df5d67936d8861464dc89c5d3fab35132626e9369379"}, - {file = "coverage-7.2.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a8723ccec4e564d4b9a79923246f7b9a8de4ec55fa03ec4ec804459dade3c4f"}, - {file = "coverage-7.2.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5906f6a84b47f995cd1bf0aca1c72d591c55ee955f98074e93660d64dfc66eb9"}, - {file = "coverage-7.2.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c139b7ab3f0b15f9aad0a3fedef5a1f8c0b2bdc291d88639ca2c97d3682416"}, - {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a5ffd45c6b93c23a8507e2f436983015c6457aa832496b6a095505ca2f63e8f1"}, - {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4f3c7c19581d471af0e9cb49d928172cd8492cd78a2b7a4e82345d33662929bb"}, - {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e8c0e79820cdd67978e1120983786422d279e07a381dbf89d03bbb23ec670a6"}, - {file = "coverage-7.2.6-cp39-cp39-win32.whl", hash = "sha256:13cde6bb0e58fb67d09e2f373de3899d1d1e866c5a9ff05d93615f2f54fbd2bb"}, - {file = "coverage-7.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:6b9f64526286255735847aed0221b189486e0b9ed943446936e41b7e44b08783"}, - {file = "coverage-7.2.6-pp37.pp38.pp39-none-any.whl", hash = "sha256:6babcbf1e66e46052442f10833cfc4a0d3554d8276aa37af8531a83ed3c1a01d"}, - {file = "coverage-7.2.6.tar.gz", hash = "sha256:2025f913f2edb0272ef15d00b1f335ff8908c921c8eb2013536fcaf61f5a683d"}, + {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, + {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, + {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, + {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, + {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, + {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, + {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, + {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, + {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, + {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, + {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, + {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, + {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, + {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, + {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, + {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, + {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, + {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, + {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, + {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, + {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, + {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, + {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, + {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, ] [package.dependencies] From 7d637ee26f4e0a7e9c476a72c065570e2e19dbf7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 May 2023 14:37:54 +0000 Subject: [PATCH 07/33] chore(deps): Bump typing-extensions from 4.6.1 to 4.6.2 (#1738) --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 438fe9922..ad2edf20c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2658,14 +2658,14 @@ files = [ [[package]] name = "typing-extensions" -version = "4.6.1" +version = "4.6.2" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.6.1-py3-none-any.whl", hash = "sha256:6bac751f4789b135c43228e72de18637e9a6c29d12777023a703fd1a6858469f"}, - {file = "typing_extensions-4.6.1.tar.gz", hash = "sha256:558bc0c4145f01e6405f4a5fdbd82050bd221b119f4bf72a961a1cfd471349d6"}, + {file = "typing_extensions-4.6.2-py3-none-any.whl", hash = "sha256:3a8b36f13dd5fdc5d1b16fe317f5668545de77fa0b8e02006381fd49d731ab98"}, + {file = "typing_extensions-4.6.2.tar.gz", hash = "sha256:06006244c70ac8ee83fa8282cb188f697b8db25bc8b4df07be1873c43897060c"}, ] [[package]] From 0b7d4a8e911a0bd5a65c463465bf9fe347a22024 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 May 2023 13:09:49 +0000 Subject: [PATCH 08/33] chore(deps): Bump cryptography from 40.0.2 to 41.0.0 (#1741) --- poetry.lock | 52 +++++++++++++++++++++++++------------------------- pyproject.toml | 2 +- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/poetry.lock b/poetry.lock index ad2edf20c..579abecd2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -591,31 +591,31 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "40.0.2" +version = "41.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b"}, - {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b"}, - {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9"}, - {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c"}, - {file = "cryptography-40.0.2-cp36-abi3-win32.whl", hash = "sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9"}, - {file = "cryptography-40.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404"}, - {file = "cryptography-40.0.2.tar.gz", hash = "sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99"}, + {file = "cryptography-41.0.0-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c5ef25d060c80d6d9f7f9892e1d41bb1c79b78ce74805b8cb4aa373cb7d5ec8"}, + {file = "cryptography-41.0.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:8362565b3835ceacf4dc8f3b56471a2289cf51ac80946f9087e66dc283a810e0"}, + {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3680248309d340fda9611498a5319b0193a8dbdb73586a1acf8109d06f25b92d"}, + {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84a165379cb9d411d58ed739e4af3396e544eac190805a54ba2e0322feb55c46"}, + {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4ab14d567f7bbe7f1cdff1c53d5324ed4d3fc8bd17c481b395db224fb405c237"}, + {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9f65e842cb02550fac96536edb1d17f24c0a338fd84eaf582be25926e993dde4"}, + {file = "cryptography-41.0.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:b7f2f5c525a642cecad24ee8670443ba27ac1fab81bba4cc24c7b6b41f2d0c75"}, + {file = "cryptography-41.0.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7d92f0248d38faa411d17f4107fc0bce0c42cae0b0ba5415505df72d751bf62d"}, + {file = "cryptography-41.0.0-cp37-abi3-win32.whl", hash = "sha256:34d405ea69a8b34566ba3dfb0521379b210ea5d560fafedf9f800a9a94a41928"}, + {file = "cryptography-41.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:344c6de9f8bda3c425b3a41b319522ba3208551b70c2ae00099c205f0d9fd3be"}, + {file = "cryptography-41.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:88ff107f211ea696455ea8d911389f6d2b276aabf3231bf72c8853d22db755c5"}, + {file = "cryptography-41.0.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b846d59a8d5a9ba87e2c3d757ca019fa576793e8758174d3868aecb88d6fc8eb"}, + {file = "cryptography-41.0.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5d0bf9b252f30a31664b6f64432b4730bb7038339bd18b1fafe129cfc2be9be"}, + {file = "cryptography-41.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5c1f7293c31ebc72163a9a0df246f890d65f66b4a40d9ec80081969ba8c78cc9"}, + {file = "cryptography-41.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bf8fc66012ca857d62f6a347007e166ed59c0bc150cefa49f28376ebe7d992a2"}, + {file = "cryptography-41.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a4fc68d1c5b951cfb72dfd54702afdbbf0fb7acdc9b7dc4301bbf2225a27714d"}, + {file = "cryptography-41.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:14754bcdae909d66ff24b7b5f166d69340ccc6cb15731670435efd5719294895"}, + {file = "cryptography-41.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0ddaee209d1cf1f180f1efa338a68c4621154de0afaef92b89486f5f96047c55"}, + {file = "cryptography-41.0.0.tar.gz", hash = "sha256:6b71f64beeea341c9b4f963b48ee3b62d62d57ba93eb120e1196b31dc1025e78"}, ] [package.dependencies] @@ -624,12 +624,12 @@ cffi = ">=1.12" [package.extras] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "check-manifest", "mypy", "ruff"] -sdist = ["setuptools-rust (>=0.11.4)"] +nox = ["nox"] +pep8test = ["black", "check-sdist", "mypy", "ruff"] +sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist"] +test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] -tox = ["tox"] [[package]] name = "darglint" @@ -2834,4 +2834,4 @@ testing = ["pytest", "pytest-durations"] [metadata] lock-version = "2.0" python-versions = "<3.12,>=3.7.1" -content-hash = "59c05b459c4b046dff2db9aa0629fd868b8865eb004cb48c9b7424bb1e7412d5" +content-hash = "e4ace691c7a3c5651576ee45fa03de04fb21abc1eb66f0ab99cf72015ab5dd2d" diff --git a/pyproject.toml b/pyproject.toml index 6f047d847..0f0c106ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,7 +45,7 @@ click = "~=8.0" fs = "^2.4.16" PyJWT = "~=2.4" requests = "^2.25.1" -cryptography = ">=3.4.6,<41.0.0" +cryptography = ">=3.4.6,<42.0.0" importlib-metadata = {version = "<5.0.0", markers = "python_version < \"3.8\""} importlib-resources = {version = "5.12.0", markers = "python_version < \"3.9\""} memoization = ">=0.3.2,<0.5.0" From 047c333054f2aecccb8597979bdf3fe9f5f6a0a6 Mon Sep 17 00:00:00 2001 From: Pat Nadolny Date: Thu, 1 Jun 2023 17:35:18 -0400 Subject: [PATCH 09/33] fix(templates): Recommend `meltano run` in target cookiecutter README (#1742) docs: target cookiecutter should use `run` --- .../target-template/{{cookiecutter.target_id}}/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookiecutter/target-template/{{cookiecutter.target_id}}/README.md b/cookiecutter/target-template/{{cookiecutter.target_id}}/README.md index 1374cc1df..983be1ce5 100644 --- a/cookiecutter/target-template/{{cookiecutter.target_id}}/README.md +++ b/cookiecutter/target-template/{{cookiecutter.target_id}}/README.md @@ -123,7 +123,7 @@ Now you can test and orchestrate using Meltano: # Test invocation: meltano invoke {{ cookiecutter.target_id }} --version # OR run a test `elt` pipeline with the Carbon Intensity sample tap: -meltano elt tap-carbon-intensity {{ cookiecutter.target_id }} +meltano run tap-carbon-intensity {{ cookiecutter.target_id }} ``` ### SDK Dev Guide From 21985720f09e4ffa54d86de56c3819d1a2fac8fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Jun 2023 13:12:24 +0000 Subject: [PATCH 10/33] chore(deps): Bump typing-extensions from 4.6.2 to 4.6.3 (#1743) --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 579abecd2..3441518a0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2658,14 +2658,14 @@ files = [ [[package]] name = "typing-extensions" -version = "4.6.2" +version = "4.6.3" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.6.2-py3-none-any.whl", hash = "sha256:3a8b36f13dd5fdc5d1b16fe317f5668545de77fa0b8e02006381fd49d731ab98"}, - {file = "typing_extensions-4.6.2.tar.gz", hash = "sha256:06006244c70ac8ee83fa8282cb188f697b8db25bc8b4df07be1873c43897060c"}, + {file = "typing_extensions-4.6.3-py3-none-any.whl", hash = "sha256:88a4153d8505aabbb4e13aacb7c486c2b4a33ca3b3f807914a9b4c844c471c26"}, + {file = "typing_extensions-4.6.3.tar.gz", hash = "sha256:d91d5919357fe7f681a9f2b5b4cb2a5f1ef0a1e9f59c4d8ff0d3491e05c0ffd5"}, ] [[package]] From 4eaca03af29fccfe04a28d5a0eb125199eb9fde9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Jun 2023 13:24:52 +0000 Subject: [PATCH 11/33] chore(deps): Bump cryptography from 41.0.0 to 41.0.1 (#1744) --- poetry.lock | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3441518a0..5f6934978 100644 --- a/poetry.lock +++ b/poetry.lock @@ -591,31 +591,31 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "41.0.0" +version = "41.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-41.0.0-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c5ef25d060c80d6d9f7f9892e1d41bb1c79b78ce74805b8cb4aa373cb7d5ec8"}, - {file = "cryptography-41.0.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:8362565b3835ceacf4dc8f3b56471a2289cf51ac80946f9087e66dc283a810e0"}, - {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3680248309d340fda9611498a5319b0193a8dbdb73586a1acf8109d06f25b92d"}, - {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84a165379cb9d411d58ed739e4af3396e544eac190805a54ba2e0322feb55c46"}, - {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4ab14d567f7bbe7f1cdff1c53d5324ed4d3fc8bd17c481b395db224fb405c237"}, - {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9f65e842cb02550fac96536edb1d17f24c0a338fd84eaf582be25926e993dde4"}, - {file = "cryptography-41.0.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:b7f2f5c525a642cecad24ee8670443ba27ac1fab81bba4cc24c7b6b41f2d0c75"}, - {file = "cryptography-41.0.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7d92f0248d38faa411d17f4107fc0bce0c42cae0b0ba5415505df72d751bf62d"}, - {file = "cryptography-41.0.0-cp37-abi3-win32.whl", hash = "sha256:34d405ea69a8b34566ba3dfb0521379b210ea5d560fafedf9f800a9a94a41928"}, - {file = "cryptography-41.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:344c6de9f8bda3c425b3a41b319522ba3208551b70c2ae00099c205f0d9fd3be"}, - {file = "cryptography-41.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:88ff107f211ea696455ea8d911389f6d2b276aabf3231bf72c8853d22db755c5"}, - {file = "cryptography-41.0.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b846d59a8d5a9ba87e2c3d757ca019fa576793e8758174d3868aecb88d6fc8eb"}, - {file = "cryptography-41.0.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5d0bf9b252f30a31664b6f64432b4730bb7038339bd18b1fafe129cfc2be9be"}, - {file = "cryptography-41.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5c1f7293c31ebc72163a9a0df246f890d65f66b4a40d9ec80081969ba8c78cc9"}, - {file = "cryptography-41.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bf8fc66012ca857d62f6a347007e166ed59c0bc150cefa49f28376ebe7d992a2"}, - {file = "cryptography-41.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a4fc68d1c5b951cfb72dfd54702afdbbf0fb7acdc9b7dc4301bbf2225a27714d"}, - {file = "cryptography-41.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:14754bcdae909d66ff24b7b5f166d69340ccc6cb15731670435efd5719294895"}, - {file = "cryptography-41.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0ddaee209d1cf1f180f1efa338a68c4621154de0afaef92b89486f5f96047c55"}, - {file = "cryptography-41.0.0.tar.gz", hash = "sha256:6b71f64beeea341c9b4f963b48ee3b62d62d57ba93eb120e1196b31dc1025e78"}, + {file = "cryptography-41.0.1-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:f73bff05db2a3e5974a6fd248af2566134d8981fd7ab012e5dd4ddb1d9a70699"}, + {file = "cryptography-41.0.1-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:1a5472d40c8f8e91ff7a3d8ac6dfa363d8e3138b961529c996f3e2df0c7a411a"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7fa01527046ca5facdf973eef2535a27fec4cb651e4daec4d043ef63f6ecd4ca"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b46e37db3cc267b4dea1f56da7346c9727e1209aa98487179ee8ebed09d21e43"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:d198820aba55660b4d74f7b5fd1f17db3aa5eb3e6893b0a41b75e84e4f9e0e4b"}, + {file = "cryptography-41.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:948224d76c4b6457349d47c0c98657557f429b4e93057cf5a2f71d603e2fc3a3"}, + {file = "cryptography-41.0.1-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:059e348f9a3c1950937e1b5d7ba1f8e968508ab181e75fc32b879452f08356db"}, + {file = "cryptography-41.0.1-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:b4ceb5324b998ce2003bc17d519080b4ec8d5b7b70794cbd2836101406a9be31"}, + {file = "cryptography-41.0.1-cp37-abi3-win32.whl", hash = "sha256:8f4ab7021127a9b4323537300a2acfb450124b2def3756f64dc3a3d2160ee4b5"}, + {file = "cryptography-41.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:1fee5aacc7367487b4e22484d3c7e547992ed726d14864ee33c0176ae43b0d7c"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9a6c7a3c87d595608a39980ebaa04d5a37f94024c9f24eb7d10262b92f739ddb"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5d092fdfedaec4cbbffbf98cddc915ba145313a6fdaab83c6e67f4e6c218e6f3"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a8e6c2de6fbbcc5e14fd27fb24414507cb3333198ea9ab1258d916f00bc3039"}, + {file = "cryptography-41.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cb33ccf15e89f7ed89b235cff9d49e2e62c6c981a6061c9c8bb47ed7951190bc"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f0ff6e18d13a3de56f609dd1fd11470918f770c6bd5d00d632076c727d35485"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7bfc55a5eae8b86a287747053140ba221afc65eb06207bedf6e019b8934b477c"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:eb8163f5e549a22888c18b0d53d6bb62a20510060a22fd5a995ec8a05268df8a"}, + {file = "cryptography-41.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:8dde71c4169ec5ccc1087bb7521d54251c016f126f922ab2dfe6649170a3b8c5"}, + {file = "cryptography-41.0.1.tar.gz", hash = "sha256:d34579085401d3f49762d2f7d6634d6b6c2ae1242202e860f4d26b046e3a1006"}, ] [package.dependencies] From cbb858a1d4545cf57e2e2750aebed8bdb20fdc99 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 10:46:26 +0000 Subject: [PATCH 12/33] chore: Release v0.28.0 (#1746) Co-authored-by: kgpayne --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- CHANGELOG.md | 23 +++++++++++++++++++ .../{{cookiecutter.tap_id}}/pyproject.toml | 4 ++-- .../{{cookiecutter.target_id}}/pyproject.toml | 4 ++-- docs/conf.py | 2 +- pyproject.toml | 4 ++-- 6 files changed, 31 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 757feff41..d43ec56a3 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -15,7 +15,7 @@ body: attributes: label: Singer SDK Version description: Version of the library you are using - placeholder: "0.27.0" + placeholder: "0.28.0" validations: required: true - type: checkboxes diff --git a/CHANGELOG.md b/CHANGELOG.md index cdddfea22..976a1bef9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v0.28.0 (2023-06-05) + +### ✨ New + +- [#1728](https://github.com/meltano/sdk/issues/1728) Add an optional Dependabot file to projects generated from templates +- [#1572](https://github.com/meltano/sdk/issues/1572) Add `batch_config` handling in `append_builtin_config()` -- _**Thanks @aaronsteers!**_ +- [#1686](https://github.com/meltano/sdk/issues/1686) Log stream errors +- [#1711](https://github.com/meltano/sdk/issues/1711) Validate records against stream schema in standard tap tests +- [#1709](https://github.com/meltano/sdk/issues/1709) Add a default Apache 2.0 license to tap and target templates + +### 🐛 Fixes + +- [#1742](https://github.com/meltano/sdk/issues/1742) Recommend `meltano run` in target cookiecutter README + +### ⚙️ Under the Hood + +- [#936](https://github.com/meltano/sdk/issues/936) Use inheritance to construct plugin CLI + +### 📚 Documentation Improvements + +- [#1721](https://github.com/meltano/sdk/issues/1721) Remove unsupported `previous_token` from HATEOAS example +- [#1703](https://github.com/meltano/sdk/issues/1703) Fix broken docs link for `record_metadata` page -- _**Thanks @menzenski!**_ + ## v0.27.0 (2023-05-11) ### ✨ New diff --git a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml index db2945348..0fd2b6581 100644 --- a/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml +++ b/cookiecutter/tap-template/{{cookiecutter.tap_id}}/pyproject.toml @@ -21,7 +21,7 @@ packages = [ [tool.poetry.dependencies] python = "<3.12,>=3.7.1" -singer-sdk = { version="^0.27.0" } +singer-sdk = { version="^0.28.0" } fs-s3fs = { version = "^1.1.1", optional = true } {%- if cookiecutter.stream_type in ["REST", "GraphQL"] %} requests = "^2.31.0" @@ -32,7 +32,7 @@ cached-property = "^1" # Remove after Python 3.7 support is dropped [tool.poetry.group.dev.dependencies] pytest = "^7.2.1" -singer-sdk = { version="^0.27.0", extras = ["testing"] } +singer-sdk = { version="^0.28.0", extras = ["testing"] } [tool.poetry.extras] s3 = ["fs-s3fs"] diff --git a/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml b/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml index 057c81deb..8d56d981c 100644 --- a/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml +++ b/cookiecutter/target-template/{{cookiecutter.target_id}}/pyproject.toml @@ -21,7 +21,7 @@ packages = [ [tool.poetry.dependencies] python = "<3.12,>=3.7.1" -singer-sdk = { version="^0.27.0" } +singer-sdk = { version="^0.28.0" } fs-s3fs = { version = "^1.1.1", optional = true } {%- if cookiecutter.serialization_method != "SQL" %} requests = "^2.31.0" @@ -29,7 +29,7 @@ requests = "^2.31.0" [tool.poetry.dev-dependencies] pytest = "^7.2.1" -singer-sdk = { version="^0.27.0", extras = ["testing"] } +singer-sdk = { version="^0.28.0", extras = ["testing"] } [tool.poetry.extras] s3 = ["fs-s3fs"] diff --git a/docs/conf.py b/docs/conf.py index 9fbbade6c..87df1b6b7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,7 +26,7 @@ author = "Meltano Core Team and Contributors" # The full version, including alpha/beta/rc tags -release = "0.27.0" +release = "0.28.0" # -- General configuration --------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index 0f0c106ae..3c0384d3c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "singer-sdk" -version = "0.27.0" +version = "0.28.0" description = "A framework for building Singer taps" authors = ["Meltano Team and Contributors"] maintainers = ["Meltano Team and Contributors"] @@ -142,7 +142,7 @@ norecursedirs = "cookiecutter" [tool.commitizen] name = "cz_version_bump" -version = "0.27.0" +version = "0.28.0" tag_format = "v$major.$minor.$patch$prerelease" version_files = [ "docs/conf.py", From fda24cfba259b917d0ab3a74b355346e7b0027e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 14:57:31 +0000 Subject: [PATCH 13/33] chore(deps): Bump actions/dependency-review-action from 3.0.4 to 3.0.6 (#1747) --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 00490561b..dc7c94bbd 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -20,7 +20,7 @@ jobs: - name: GitHub dependency vulnerability check if: ${{ github.event_name == 'pull_request_target' }} - uses: actions/dependency-review-action@v3.0.4 + uses: actions/dependency-review-action@v3.0.6 with: fail-on-severity: high From 07a63c2c17b146b52b7244d2d707d2df9012598d Mon Sep 17 00:00:00 2001 From: mjsqu Date: Tue, 6 Jun 2023 11:34:22 +1200 Subject: [PATCH 14/33] refactor(taps): Change `SQLStream.schema` into a cached property (#1745) * Change schema into a cached_property Schema is called at least once per record and does not change within a stream, so it should be cached for performance benefits. * Fix missing sys import * Changes for 3.7 compatibility ``` @property @lru_cache() ``` is a backwards compatible version of functools.cached_property for Python 3.7 https://stackoverflow.com/questions/4037481/caching-class-attributes-in-python * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add parentheses to lru_cache for py 3.7 * Fix schema return type mypy checks fail because the schema return type is lru_cache: ``` singer_sdk/streams/sql.py:82: error: Signature of "schema" incompatible with supertype "Stream" [override] singer_sdk/streams/sql.py:154: error: Argument "schema" to "get_selected_schema" has incompatible type "_lru_cache_wrapper[Dict[Any, Any]]"; expected "Dict[Any, Any]" [arg-type] Found 2 errors in 1 file (checked 59 source files) ``` The update should pass over the `_lru_cache_wrapper` type and return a `Dict` as expected * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix for mypy - Remove `lru_cache` - Set `_cached_schema` up as a class variable to hold the schema for each stream - Check for presence of `self._cached_schema` on the stream * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Re-add removed TYPE_CHECKING * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Edgar R. M --- singer_sdk/streams/sql.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/singer_sdk/streams/sql.py b/singer_sdk/streams/sql.py index 3d3de5bbe..7a3fe3886 100644 --- a/singer_sdk/streams/sql.py +++ b/singer_sdk/streams/sql.py @@ -20,6 +20,7 @@ class SQLStream(Stream, metaclass=abc.ABCMeta): """Base class for SQLAlchemy-based streams.""" connector_class = SQLConnector + _cached_schema: dict | None = None def __init__( self, @@ -74,7 +75,7 @@ def metadata(self) -> MetadataMapping: """ return self._singer_catalog_entry.metadata - @property + @property # TODO: Investigate @cached_property after py > 3.7 def schema(self) -> dict: """Return metadata object (dict) as specified in the Singer spec. @@ -83,7 +84,13 @@ def schema(self) -> dict: Returns: The schema object. """ - return t.cast(dict, self._singer_catalog_entry.schema.to_dict()) + if not self._cached_schema: + self._cached_schema = t.cast( + dict, + self._singer_catalog_entry.schema.to_dict(), + ) + + return self._cached_schema @property def tap_stream_id(self) -> str: From 5267160fda096e07ba6ec86725fd98aa9cee9ae9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 22:16:23 -0600 Subject: [PATCH 15/33] chore: pre-commit autoupdate (#1751) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/python-jsonschema/check-jsonschema: 0.23.0 → 0.23.1](https://github.com/python-jsonschema/check-jsonschema/compare/0.23.0...0.23.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .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 8d308ac62..3b4bcc315 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: )$ - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.23.0 + rev: 0.23.1 hooks: - id: check-dependabot - id: check-github-workflows From a64c66063998859c50f690c46b9de67c3c4cf33e Mon Sep 17 00:00:00 2001 From: "Edgar R. M" Date: Wed, 7 Jun 2023 04:56:39 -0600 Subject: [PATCH 16/33] chore: Add `Cookiecutter templates` to feature issue template (#1716) --- .github/ISSUE_TEMPLATE/feature.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml index 0c084de5b..ad08d3e6a 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -20,6 +20,7 @@ body: - Targets (data type handling, batching, SQL object generation, etc.) - Configuration (settings parsing, validation, etc.) - CLI (options, error messages, logging, etc.) + - Cookiecutter templates - Other validations: required: true From cf5743901c1b87ad9691e0136b1b08fb42680a6e Mon Sep 17 00:00:00 2001 From: "Edgar R. M" Date: Wed, 7 Jun 2023 08:02:12 -0600 Subject: [PATCH 17/33] fix(taps): Always emit a STATE message at the start of the sync process (#1753) --- singer_sdk/tap_base.py | 4 ++- tests/core/test_parent_child.py | 28 +++++++++---------- tests/samples/test_tap_countries.py | 2 +- .../mapped_stream/aliased_stream.jsonl | 1 + .../changed_key_properties.jsonl | 1 + .../mapped_stream/drop_property.jsonl | 1 + .../drop_property_null_string.jsonl | 1 + .../snapshots/mapped_stream/flatten_all.jsonl | 1 + .../mapped_stream/flatten_depth_1.jsonl | 1 + .../mapped_stream/keep_all_fields.jsonl | 1 + .../mapped_stream/map_and_flatten.jsonl | 1 + tests/snapshots/mapped_stream/no_map.jsonl | 1 + .../mapped_stream/non_pk_passthrough.jsonl | 1 + .../mapped_stream/only_mapped_fields.jsonl | 1 + .../only_mapped_fields_null_string.jsonl | 1 + .../mapped_stream/sourced_stream_1.jsonl | 1 + .../sourced_stream_1_null_string.jsonl | 1 + .../mapped_stream/sourced_stream_2.jsonl | 1 + 18 files changed, 33 insertions(+), 16 deletions(-) diff --git a/singer_sdk/tap_base.py b/singer_sdk/tap_base.py index e6d999a02..23d8e815b 100644 --- a/singer_sdk/tap_base.py +++ b/singer_sdk/tap_base.py @@ -11,7 +11,7 @@ import click -from singer_sdk._singerlib import Catalog +from singer_sdk._singerlib import Catalog, StateMessage, write_message from singer_sdk.configuration._dict_config import merge_missing_config_jsonschema from singer_sdk.exceptions import AbortedSyncFailedException, AbortedSyncPausedException from singer_sdk.helpers import _state @@ -431,6 +431,8 @@ def sync_all(self) -> None: """Sync all streams.""" self._reset_state_progress_markers() self._set_compatible_replication_methods() + write_message(StateMessage(value=self.state)) + stream: Stream for stream in self.streams.values(): if not stream.selected and not stream.has_selected_descendents: diff --git a/tests/core/test_parent_child.py b/tests/core/test_parent_child.py index 5d7d4f2de..a91726bc3 100644 --- a/tests/core/test_parent_child.py +++ b/tests/core/test_parent_child.py @@ -103,19 +103,19 @@ def test_parent_context_fields_in_child(tap: MyTap): messages = _get_messages(tap) # Parent schema is emitted - assert messages[0] - assert messages[0]["type"] == SingerMessageType.SCHEMA - assert messages[0]["stream"] == parent_stream.name - assert messages[0]["schema"] == parent_stream.schema - - # Child schema is emitted assert messages[1] assert messages[1]["type"] == SingerMessageType.SCHEMA - assert messages[1]["stream"] == child_stream.name - assert messages[1]["schema"] == child_stream.schema + assert messages[1]["stream"] == parent_stream.name + assert messages[1]["schema"] == parent_stream.schema + + # Child schema is emitted + assert messages[2] + assert messages[2]["type"] == SingerMessageType.SCHEMA + assert messages[2]["stream"] == child_stream.name + assert messages[2]["schema"] == child_stream.schema # Child records are emitted - child_record_messages = messages[2:5] + child_record_messages = messages[3:6] assert child_record_messages assert all(msg["type"] == SingerMessageType.RECORD for msg in child_record_messages) assert all(msg["stream"] == child_stream.name for msg in child_record_messages) @@ -155,13 +155,13 @@ def test_child_deselected_parent(tap_with_deselected_parent: MyTap): messages = _get_messages(tap_with_deselected_parent) # First message is a schema for the child stream, not the parent - assert messages[0] - assert messages[0]["type"] == SingerMessageType.SCHEMA - assert messages[0]["stream"] == child_stream.name - assert messages[0]["schema"] == child_stream.schema + assert messages[1] + assert messages[1]["type"] == SingerMessageType.SCHEMA + assert messages[1]["stream"] == child_stream.name + assert messages[1]["schema"] == child_stream.schema # Child records are emitted - child_record_messages = messages[1:4] + child_record_messages = messages[2:5] assert child_record_messages assert all(msg["type"] == SingerMessageType.RECORD for msg in child_record_messages) assert all(msg["stream"] == child_stream.name for msg in child_record_messages) diff --git a/tests/samples/test_tap_countries.py b/tests/samples/test_tap_countries.py index 5e7a5cb98..f822f5c8b 100644 --- a/tests/samples/test_tap_countries.py +++ b/tests/samples/test_tap_countries.py @@ -135,4 +135,4 @@ def tally_messages(messages: list) -> t.Counter: assert counter["SCHEMA", "countries"] == 1 assert counter["BATCH", "countries"] == 1 - assert counter[("STATE",)] == 2 + assert counter[("STATE",)] == 3 diff --git a/tests/snapshots/mapped_stream/aliased_stream.jsonl b/tests/snapshots/mapped_stream/aliased_stream.jsonl index 49089dda9..46d5daffe 100644 --- a/tests/snapshots/mapped_stream/aliased_stream.jsonl +++ b/tests/snapshots/mapped_stream/aliased_stream.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "aliased_stream", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []} {"type": "RECORD", "stream": "aliased_stream", "record": {"email": "alice@example.com", "count": 21, "user": {"id": 1, "sub": {"num": 1}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "aliased_stream", "record": {"email": "bob@example.com", "count": 13, "user": {"id": 2, "sub": {"num": 2}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/changed_key_properties.jsonl b/tests/snapshots/mapped_stream/changed_key_properties.jsonl index f62049ce8..c5168a45b 100644 --- a/tests/snapshots/mapped_stream/changed_key_properties.jsonl +++ b/tests/snapshots/mapped_stream/changed_key_properties.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "mystream", "schema": {"type": "object", "properties": {"email_hash": {"type": ["string", "null"]}}}, "key_properties": ["email_hash"]} {"type": "RECORD", "stream": "mystream", "record": {"email_hash": "c160f8cc69a4f0bf2b0362752353d060"}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "mystream", "record": {"email_hash": "4b9bb80620f03eb3719e0a061c14283d"}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/drop_property.jsonl b/tests/snapshots/mapped_stream/drop_property.jsonl index f4b0b6f71..8694f4736 100644 --- a/tests/snapshots/mapped_stream/drop_property.jsonl +++ b/tests/snapshots/mapped_stream/drop_property.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []} {"type": "RECORD", "stream": "mystream", "record": {"count": 21, "user": {"id": 1, "sub": {"num": 1}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "mystream", "record": {"count": 13, "user": {"id": 2, "sub": {"num": 2}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/drop_property_null_string.jsonl b/tests/snapshots/mapped_stream/drop_property_null_string.jsonl index f4b0b6f71..8694f4736 100644 --- a/tests/snapshots/mapped_stream/drop_property_null_string.jsonl +++ b/tests/snapshots/mapped_stream/drop_property_null_string.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []} {"type": "RECORD", "stream": "mystream", "record": {"count": 21, "user": {"id": 1, "sub": {"num": 1}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "mystream", "record": {"count": 13, "user": {"id": 2, "sub": {"num": 2}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/flatten_all.jsonl b/tests/snapshots/mapped_stream/flatten_all.jsonl index 03e7af0cc..c54db1563 100644 --- a/tests/snapshots/mapped_stream/flatten_all.jsonl +++ b/tests/snapshots/mapped_stream/flatten_all.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user__id": {"type": ["integer", "null"]}, "user__sub__num": {"type": ["integer", "null"]}}, "type": "object"}, "key_properties": []} {"type": "RECORD", "stream": "mystream", "record": {"email": "alice@example.com", "count": 21, "user__id": 1, "user__sub__num": 1}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "mystream", "record": {"email": "bob@example.com", "count": 13, "user__id": 2, "user__sub__num": 2}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/flatten_depth_1.jsonl b/tests/snapshots/mapped_stream/flatten_depth_1.jsonl index 6765ccdef..275e3295c 100644 --- a/tests/snapshots/mapped_stream/flatten_depth_1.jsonl +++ b/tests/snapshots/mapped_stream/flatten_depth_1.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user__id": {"type": ["integer", "null"]}, "user__sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []} {"type": "RECORD", "stream": "mystream", "record": {"email": "alice@example.com", "count": 21, "user__id": 1, "user__sub": "{\"num\": 1}"}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "mystream", "record": {"email": "bob@example.com", "count": 13, "user__id": 2, "user__sub": "{\"num\": 2}"}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/keep_all_fields.jsonl b/tests/snapshots/mapped_stream/keep_all_fields.jsonl index 2be7c1105..13ddce438 100644 --- a/tests/snapshots/mapped_stream/keep_all_fields.jsonl +++ b/tests/snapshots/mapped_stream/keep_all_fields.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": ["object", "null"]}, "email_hash": {"type": ["string", "null"]}}, "type": "object"}, "key_properties": []} {"type": "RECORD", "stream": "mystream", "record": {"email": "alice@example.com", "count": 21, "user": {"id": 1, "sub": {"num": 1}}, "email_hash": "c160f8cc69a4f0bf2b0362752353d060"}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "mystream", "record": {"email": "bob@example.com", "count": 13, "user": {"id": 2, "sub": {"num": 2}}, "email_hash": "4b9bb80620f03eb3719e0a061c14283d"}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/map_and_flatten.jsonl b/tests/snapshots/mapped_stream/map_and_flatten.jsonl index 40ecc7e40..bf2620184 100644 --- a/tests/snapshots/mapped_stream/map_and_flatten.jsonl +++ b/tests/snapshots/mapped_stream/map_and_flatten.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user__id": {"type": ["integer", "null"]}, "user__sub__num": {"type": ["integer", "null"]}, "email_hash": {"type": ["string", "null"]}}, "type": "object"}, "key_properties": ["email_hash"]} {"type": "RECORD", "stream": "mystream", "record": {"email": "alice@example.com", "count": 21, "user__id": 1, "user__sub__num": 1, "email_hash": "c160f8cc69a4f0bf2b0362752353d060"}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "mystream", "record": {"email": "bob@example.com", "count": 13, "user__id": 2, "user__sub__num": 2, "email_hash": "4b9bb80620f03eb3719e0a061c14283d"}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/no_map.jsonl b/tests/snapshots/mapped_stream/no_map.jsonl index f2eeb77fd..019b1f9d9 100644 --- a/tests/snapshots/mapped_stream/no_map.jsonl +++ b/tests/snapshots/mapped_stream/no_map.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "mystream", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []} {"type": "RECORD", "stream": "mystream", "record": {"email": "alice@example.com", "count": 21, "user": {"id": 1, "sub": {"num": 1}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "mystream", "record": {"email": "bob@example.com", "count": 13, "user": {"id": 2, "sub": {"num": 2}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/non_pk_passthrough.jsonl b/tests/snapshots/mapped_stream/non_pk_passthrough.jsonl index 4c2490c6c..0cbbf451a 100644 --- a/tests/snapshots/mapped_stream/non_pk_passthrough.jsonl +++ b/tests/snapshots/mapped_stream/non_pk_passthrough.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "mystream", "schema": {"type": "object", "properties": {"count": {"type": ["integer", "null"]}}}, "key_properties": []} {"type": "RECORD", "stream": "mystream", "record": {"count": 21}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "mystream", "record": {"count": 13}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/only_mapped_fields.jsonl b/tests/snapshots/mapped_stream/only_mapped_fields.jsonl index d5341c622..e53042958 100644 --- a/tests/snapshots/mapped_stream/only_mapped_fields.jsonl +++ b/tests/snapshots/mapped_stream/only_mapped_fields.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "mystream", "schema": {"type": "object", "properties": {"email_hash": {"type": ["string", "null"]}, "fixed_count": {"type": ["integer", "null"]}}}, "key_properties": []} {"type": "RECORD", "stream": "mystream", "record": {"email_hash": "c160f8cc69a4f0bf2b0362752353d060", "fixed_count": 20}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "mystream", "record": {"email_hash": "4b9bb80620f03eb3719e0a061c14283d", "fixed_count": 12}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/only_mapped_fields_null_string.jsonl b/tests/snapshots/mapped_stream/only_mapped_fields_null_string.jsonl index d5341c622..e53042958 100644 --- a/tests/snapshots/mapped_stream/only_mapped_fields_null_string.jsonl +++ b/tests/snapshots/mapped_stream/only_mapped_fields_null_string.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "mystream", "schema": {"type": "object", "properties": {"email_hash": {"type": ["string", "null"]}, "fixed_count": {"type": ["integer", "null"]}}}, "key_properties": []} {"type": "RECORD", "stream": "mystream", "record": {"email_hash": "c160f8cc69a4f0bf2b0362752353d060", "fixed_count": 20}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "mystream", "record": {"email_hash": "4b9bb80620f03eb3719e0a061c14283d", "fixed_count": 12}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/sourced_stream_1.jsonl b/tests/snapshots/mapped_stream/sourced_stream_1.jsonl index 3d83ea30e..e63d03815 100644 --- a/tests/snapshots/mapped_stream/sourced_stream_1.jsonl +++ b/tests/snapshots/mapped_stream/sourced_stream_1.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "sourced_stream_1", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []} {"type": "RECORD", "stream": "sourced_stream_1", "record": {"email": "alice@example.com", "count": 21, "user": {"id": 1, "sub": {"num": 1}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "sourced_stream_1", "record": {"email": "bob@example.com", "count": 13, "user": {"id": 2, "sub": {"num": 2}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/sourced_stream_1_null_string.jsonl b/tests/snapshots/mapped_stream/sourced_stream_1_null_string.jsonl index 3d83ea30e..e63d03815 100644 --- a/tests/snapshots/mapped_stream/sourced_stream_1_null_string.jsonl +++ b/tests/snapshots/mapped_stream/sourced_stream_1_null_string.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "sourced_stream_1", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []} {"type": "RECORD", "stream": "sourced_stream_1", "record": {"email": "alice@example.com", "count": 21, "user": {"id": 1, "sub": {"num": 1}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "sourced_stream_1", "record": {"email": "bob@example.com", "count": 13, "user": {"id": 2, "sub": {"num": 2}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} diff --git a/tests/snapshots/mapped_stream/sourced_stream_2.jsonl b/tests/snapshots/mapped_stream/sourced_stream_2.jsonl index 6a378a5ca..41cce23d7 100644 --- a/tests/snapshots/mapped_stream/sourced_stream_2.jsonl +++ b/tests/snapshots/mapped_stream/sourced_stream_2.jsonl @@ -1,3 +1,4 @@ +{"type": "STATE", "value": {}} {"type": "SCHEMA", "stream": "sourced_stream_2", "schema": {"properties": {"email": {"type": ["string", "null"]}, "count": {"type": ["integer", "null"]}, "user": {"properties": {"id": {"type": ["integer", "null"]}, "sub": {"properties": {"num": {"type": ["integer", "null"]}}, "type": ["object", "null"]}}, "type": ["object", "null"]}}, "type": "object"}, "key_properties": []} {"type": "RECORD", "stream": "sourced_stream_2", "record": {"email": "alice@example.com", "count": 21, "user": {"id": 1, "sub": {"num": 1}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} {"type": "RECORD", "stream": "sourced_stream_2", "record": {"email": "bob@example.com", "count": 13, "user": {"id": 2, "sub": {"num": 2}}}, "time_extracted": "2022-01-01T00:00:00+00:00"} From 6296599a6955d8239e04cfb7ccaa0963dcc0ae4b Mon Sep 17 00:00:00 2001 From: Ken Payne Date: Wed, 7 Jun 2023 16:08:51 +0100 Subject: [PATCH 18/33] fix: change runner scope to function for target tests (#1752) Co-authored-by: Edgar R. M --- samples/sample_target_csv/csv_target_sink.py | 1 + .../parquet_target_sink.py | 22 +- singer_sdk/testing/__init__.py | 3 +- singer_sdk/testing/factory.py | 487 ++++++++++++------ singer_sdk/testing/runners.py | 2 +- singer_sdk/testing/target_tests.py | 16 + tests/samples/test_target_parquet.py | 4 +- 7 files changed, 359 insertions(+), 176 deletions(-) diff --git a/samples/sample_target_csv/csv_target_sink.py b/samples/sample_target_csv/csv_target_sink.py index f06c3163d..4f02bf0bb 100644 --- a/samples/sample_target_csv/csv_target_sink.py +++ b/samples/sample_target_csv/csv_target_sink.py @@ -41,6 +41,7 @@ def process_batch(self, context: dict) -> None: delimiter="\t", quotechar='"', quoting=csv.QUOTE_NONNUMERIC, + escapechar="\\", ) for record in records_to_drain: if newfile and not records_written: diff --git a/samples/sample_target_parquet/parquet_target_sink.py b/samples/sample_target_parquet/parquet_target_sink.py index 40691c13c..e98dca2b1 100644 --- a/samples/sample_target_parquet/parquet_target_sink.py +++ b/samples/sample_target_parquet/parquet_target_sink.py @@ -36,7 +36,8 @@ def _json_schema_to_arrow_fields(schema: dict[str, t.Any]) -> pa.StructType: for name, property_schema in schema.get("properties", {}).items(): field = pa.field(name, _json_type_to_arrow_field(property_schema)) fields.append(field) - return fields + + return fields if fields else [pa.field("dummy", pa.string())] def _json_type_to_arrow_field( # noqa: PLR0911 @@ -99,22 +100,3 @@ def process_batch(self, context: dict) -> None: table = pa.Table.from_pylist(records_to_drain, schema=schema) writer.write_table(table) writer.close() - - @staticmethod - def translate_data_type(singer_type: str | dict) -> t.Any: - """Translate from singer_type to a native type.""" - if singer_type in ["decimal", "float", "double"]: - return pa.decimal128 - if singer_type in ["date-time"]: - return pa.datetime - if singer_type in ["date"]: - return pa.date64 - return pa.string - - def _get_parquet_schema(self) -> list[tuple[str, t.Any]]: - col_list: list[tuple[str, t.Any]] = [] - for prop in self.schema["properties"]: - col_list.append( - (prop["name"], self.translate_data_type(prop["type"])), - ) - return col_list diff --git a/singer_sdk/testing/__init__.py b/singer_sdk/testing/__init__.py index 3ca07d964..24ce4ac9f 100644 --- a/singer_sdk/testing/__init__.py +++ b/singer_sdk/testing/__init__.py @@ -3,7 +3,7 @@ from __future__ import annotations from .config import SuiteConfig -from .factory import get_tap_test_class, get_target_test_class, get_test_class +from .factory import get_tap_test_class, get_target_test_class from .legacy import ( _get_tap_catalog, _select_all, @@ -19,7 +19,6 @@ __all__ = [ "get_tap_test_class", "get_target_test_class", - "get_test_class", "_get_tap_catalog", "_select_all", "get_standard_tap_tests", diff --git a/singer_sdk/testing/factory.py b/singer_sdk/testing/factory.py index 32c9e6469..99c9058c4 100644 --- a/singer_sdk/testing/factory.py +++ b/singer_sdk/testing/factory.py @@ -19,134 +19,331 @@ from singer_sdk import Tap, Target -def get_test_class( # noqa: C901 - test_runner: TapTestRunner | TargetTestRunner, - test_suites: list, - suite_config: SuiteConfig | None, -) -> object: - """Construct a valid pytest test class from given suites. - - Args: - test_runner: A Tap or Target test runner instance. - test_suites: A list of Test Suits to apply. - suite_config: SuiteConfig instance to pass to tests. - - Returns: - A test class usable by pytest. - """ - - class BaseTestClass: - """Base test class.""" - - params: dict = {} - param_ids: dict = {} - - @pytest.fixture - def config(self) -> SuiteConfig: - return suite_config or SuiteConfig() - - @pytest.fixture - def resource(self) -> t.Any: # noqa: ANN401, PT004 - yield # noqa: PT022 - - @pytest.fixture(scope="class") - def runner(self) -> TapTestRunner | TargetTestRunner: - # Populate runner class with cached records for use in tests - test_runner.sync_all() - return test_runner - - for suite in test_suites: - # make sure given runner is of type TapTestRunner - expected_runner_class = ( - TapTestRunner - if suite.kind in {"tap", "tap_stream", "tap_stream_attribute"} - else TargetTestRunner +class BaseTestClass: + """Base test class.""" + + params: dict = {} + param_ids: dict = {} + + +class TapTestClassFactory: + """Factory for Tap Test Classes.""" + + def __init__( + self, + tap_class: type[Tap], + *, + config: dict | None = None, + ): + """Initialize TapTestClassFactory. + + Args: + tap_class: Tap class to be tested. + config: Tap configuration for testing. + """ + self.tap_class = tap_class + self.config = config + + def new_test_class( + self, + *, + include_tap_tests: bool = True, + include_stream_tests: bool = True, + include_stream_attribute_tests: bool = True, + custom_suites: list | None = None, + suite_config: SuiteConfig | None = None, + **kwargs: t.Any, + ) -> type[BaseTestClass]: + """Get a new test class. + + Args: + include_tap_tests: Include tap tests in the test class. + include_stream_tests: Include stream tests in the test class. + include_stream_attribute_tests: + Include stream attribute tests in the test class. + custom_suites: List of custom test suites to include in the test class. + suite_config: SuiteConfig instance to be used when instantiating tests. + kwargs: Default arguments to be passed to tap on create. + + Returns: + A new test class. + """ + # compile test suites + suites = custom_suites or [] + if include_tap_tests: + suites.append(tap_tests) + if include_stream_tests: + suites.append(tap_stream_tests) + if include_stream_attribute_tests: + suites.append(tap_stream_attribute_tests) + + # set default values + if "parse_env_config" not in kwargs: + kwargs["parse_env_config"] = True + + # create singleton test runner + test_runner = TapTestRunner( + tap_class=self.tap_class, + config=self.config, + suite_config=suite_config, + **kwargs, ) - assert isinstance(test_runner, expected_runner_class), ( - f"Test suite of kind {suite.kind} passed, " - f"but test runner if of type {type(test_runner)}." + + empty_test_class = self._get_empty_test_class( + test_runner=test_runner, + suite_config=suite_config, ) - test_runner = t.cast( - expected_runner_class, # type: ignore[valid-type] - test_runner, + return self._annotate_test_class( + empty_test_class=empty_test_class, + test_suites=suites, + test_runner=test_runner, ) - if suite.kind in {"tap", "target"}: - for test_class in suite.tests: - test = test_class() - test_name = f"test_{suite.kind}_{test.name}" - setattr(BaseTestClass, f"test_{suite.kind}_{test.name}", test.run) - - if suite.kind in {"tap_stream", "tap_stream_attribute"}: - streams = list(test_runner.new_tap().streams.values()) - - if suite.kind == "tap_stream": - params = [ - { - "stream": stream, - } - for stream in streams - ] - param_ids = [stream.name for stream in streams] - + def _get_empty_test_class( + self, + test_runner: TapTestRunner, + suite_config: SuiteConfig | None, + ) -> type[BaseTestClass]: + """Get an empty test class. + + Args: + test_runner: Test runner to be used in the test class. + suite_config: SuiteConfig instance to be used when instantiating tests. + + Returns: + An empty test class. + """ + + class TapTestClass(BaseTestClass): + """Tap Test Class.""" + + @pytest.fixture + def config(self) -> SuiteConfig: + return suite_config or SuiteConfig() + + @pytest.fixture + def resource(self) -> t.Any: # noqa: ANN401, PT004 + yield # noqa: PT022 + + @pytest.fixture(scope="class") + def runner(self) -> TapTestRunner | TargetTestRunner: + # Populate runner class with cached records for use in tests + test_runner.sync_all() + return test_runner + + return TapTestClass + + def _annotate_test_class( # noqa: C901 + self, + empty_test_class: type[BaseTestClass], + test_suites: list, + test_runner: TapTestRunner, + ) -> type[BaseTestClass]: + """Annotate test class with test methods. + + Args: + empty_test_class: Empty test class to be annotated. + test_suites: List of test suites to include in the test class. + test_runner: Test runner to be used in the test class. + + Returns: + An annotated test class. + """ + for suite in test_suites: + if suite.kind == "tap": for test_class in suite.tests: test = test_class() test_name = f"test_{suite.kind}_{test.name}" - setattr( - BaseTestClass, - test_name, - test.run, - ) - BaseTestClass.params[test_name] = params - BaseTestClass.param_ids[test_name] = param_ids - - if suite.kind == "tap_stream_attribute": - for test_class in suite.tests: - test = test_class() - test_name = f"test_{suite.kind}_{test.name}" - test_params = [] - test_ids = [] - for stream in streams: - test_params.extend( - [ - { - "stream": stream, - "attribute_name": property_name, - } - for property_name, property_schema in stream.schema[ - "properties" - ].items() - if test_class.evaluate( - stream=stream, - property_name=property_name, - property_schema=property_schema, - ) - ], - ) - test_ids.extend( - [ - f"{stream.name}.{property_name}" - for property_name, property_schema in stream.schema[ - "properties" - ].items() - if test_class.evaluate( - stream=stream, - property_name=property_name, - property_schema=property_schema, - ) - ], - ) - - if test_params: + setattr(empty_test_class, test_name, test.run) + + if suite.kind in {"tap_stream", "tap_stream_attribute"}: + streams = list(test_runner.new_tap().streams.values()) + + if suite.kind == "tap_stream": + params = [ + { + "stream": stream, + } + for stream in streams + ] + param_ids = [stream.name for stream in streams] + + for test_class in suite.tests: + test = test_class() + test_name = f"test_{suite.kind}_{test.name}" setattr( - BaseTestClass, + empty_test_class, test_name, test.run, ) - BaseTestClass.params[test_name] = test_params - BaseTestClass.param_ids[test_name] = test_ids + empty_test_class.params[test_name] = params + empty_test_class.param_ids[test_name] = param_ids + + if suite.kind == "tap_stream_attribute": + for test_class in suite.tests: + test = test_class() + test_name = f"test_{suite.kind}_{test.name}" + test_params = [] + test_ids = [] + for stream in streams: + test_params.extend( + [ + { + "stream": stream, + "attribute_name": property_name, + } + for property_name, property_schema in stream.schema[ + "properties" + ].items() + if test_class.evaluate( + stream=stream, + property_name=property_name, + property_schema=property_schema, + ) + ], + ) + test_ids.extend( + [ + f"{stream.name}.{property_name}" + for property_name, property_schema in stream.schema[ + "properties" + ].items() + if test_class.evaluate( + stream=stream, + property_name=property_name, + property_schema=property_schema, + ) + ], + ) + + if test_params: + setattr( + empty_test_class, + test_name, + test.run, + ) + empty_test_class.params[test_name] = test_params + empty_test_class.param_ids[test_name] = test_ids + + return empty_test_class + + +class TargetTestClassFactory: + """Factory for Target Test Classes.""" + + def __init__(self, target_class: type[Target], *, config: dict | None = None): + """Initialize TargetTestClassFactory. + + Args: + target_class: Target class to be tested. + config: Config to be used when instantiating tests. + """ + self.target_class = target_class + self.config = config + + def new_test_class( + self, + *, + custom_suites: list | None = None, + suite_config: SuiteConfig | None = None, + include_target_tests: bool = True, + **kwargs: t.Any, + ) -> type[BaseTestClass]: + """Get a new Target test class. + + Args: + custom_suites: List of custom test suites to include in the test class. + suite_config: SuiteConfig instance to be used when instantiating tests. + include_target_tests: Whether to include target tests in the test class. + kwargs: Keyword arguments to be passed to the Target on run. + + Returns: + A new Target test class. + """ + # compile test suites + suites = custom_suites or [] + if include_target_tests: + suites.append(target_tests) + + # set default values + if "parse_env_config" not in kwargs: + kwargs["parse_env_config"] = True + + empty_test_class = self._get_empty_test_class( + target_class=self.target_class, + config=self.config, + suite_config=suite_config, + **kwargs, + ) + return self._annotate_test_class( + empty_test_class=empty_test_class, + test_suites=suites, + ) + + def _get_empty_test_class( + self, + target_class: type[Target], + suite_config: SuiteConfig | None, + config: dict | None = None, + **kwargs: t.Any, + ) -> type[BaseTestClass]: + """Get an empty test class. + + Args: + target_class: Target class to be tested. + suite_config: SuiteConfig instance to be used when instantiating tests. + config: Config to be used when instantiating tests. + kwargs: Keyword arguments to be passed to the Target on run. + + Returns: + An empty test class. + """ + + class TargetTestClass(BaseTestClass): + """Target Test Class.""" + + @pytest.fixture + def config(self) -> SuiteConfig: + return suite_config or SuiteConfig() + + @pytest.fixture + def resource(self) -> t.Any: # noqa: ANN401, PT004 + yield # noqa: PT022 + + @pytest.fixture + def runner(self) -> TargetTestRunner: + # Instantiate new runner class and populate records for use in tests + return TargetTestRunner( + target_class=target_class, + config=config, + suite_config=suite_config, + **kwargs, + ) + + return TargetTestClass + + def _annotate_test_class( + self, + empty_test_class: type[BaseTestClass], + test_suites: list, + ) -> type[BaseTestClass]: + """Annotate test class with test methods. + + Args: + empty_test_class: Empty test class to be annotated. + test_suites: List of test suites to be included in the test class. + + Returns: + Annotated test class. + """ + for suite in test_suites: + if suite.kind == "target": + for test_class in suite.tests: + test = test_class() + test_name = f"test_{suite.kind}_{test.name}" + setattr(empty_test_class, test_name, test.run) - return BaseTestClass + return empty_test_class def get_tap_test_class( @@ -159,7 +356,7 @@ def get_tap_test_class( custom_suites: list | None = None, suite_config: SuiteConfig | None = None, **kwargs: t.Any, -) -> object: +) -> type[BaseTestClass]: """Get Tap Test Class. Args: @@ -175,27 +372,17 @@ def get_tap_test_class( Returns: A test class usable by pytest. """ - suites = custom_suites or [] - if include_tap_tests: - suites.append(tap_tests) - if include_stream_tests: - suites.append(tap_stream_tests) - if include_stream_attribute_tests: - suites.append(tap_stream_attribute_tests) - - # set default values - if "parse_env_config" not in kwargs: - kwargs["parse_env_config"] = True - - return get_test_class( - test_runner=TapTestRunner( - tap_class=tap_class, - config=config, - suite_config=suite_config, - **kwargs, - ), - test_suites=suites, + factory = TapTestClassFactory( + tap_class=tap_class, + config=config, + ) + return factory.new_test_class( + custom_suites=custom_suites, suite_config=suite_config, + include_tap_tests=include_tap_tests, + include_stream_tests=include_stream_tests, + include_stream_attribute_tests=include_stream_attribute_tests, + **kwargs, ) @@ -205,8 +392,9 @@ def get_target_test_class( config: dict | None = None, custom_suites: list | None = None, suite_config: SuiteConfig | None = None, + include_target_tests: bool = True, **kwargs: t.Any, -) -> object: +) -> type[BaseTestClass]: """Get Target Test Class. Args: @@ -214,24 +402,19 @@ def get_target_test_class( config: Config dict to use for testing. custom_suites: Custom test suites to add to standard tests. suite_config: SuiteConfig instance to pass to tests. + include_target_tests: Include standard target tests. kwargs: Keyword arguments to pass to the TapRunner. Returns: A test class usable by pytest. """ - suites = custom_suites or [] - suites.append(target_tests) - - # set default values - if "parse_env_config" not in kwargs: - kwargs["parse_env_config"] = True - - return get_test_class( - test_runner=TargetTestRunner( - target_class=target_class, - config=config, - **kwargs, - ), - test_suites=suites, + factory = TargetTestClassFactory( + target_class=target_class, + config=config, + ) + return factory.new_test_class( + custom_suites=custom_suites, suite_config=suite_config, + include_target_tests=include_target_tests, + **kwargs, ) diff --git a/singer_sdk/testing/runners.py b/singer_sdk/testing/runners.py index c32461d6b..16f2ba905 100644 --- a/singer_sdk/testing/runners.py +++ b/singer_sdk/testing/runners.py @@ -242,7 +242,7 @@ def target_input(self) -> t.IO[str]: if self.input_io: self._input = self.input_io elif self.input_filepath: - self._input = Path(self.input_filepath).open() + self._input = Path(self.input_filepath).open(encoding="utf8") return t.cast(t.IO[str], self._input) @target_input.setter diff --git a/singer_sdk/testing/target_tests.py b/singer_sdk/testing/target_tests.py index 50e48622a..8b582ed12 100644 --- a/singer_sdk/testing/target_tests.py +++ b/singer_sdk/testing/target_tests.py @@ -2,6 +2,8 @@ from __future__ import annotations +import pytest + from .templates import TargetFileTestTemplate, TargetTestTemplate @@ -52,6 +54,13 @@ class TargetInvalidSchemaTest(TargetFileTestTemplate): name = "invalid_schema" + def test(self) -> None: + """Run test.""" + # TODO: the SDK should raise a better error than Exception in this case + # https://github.com/meltano/sdk/issues/1755 + with pytest.raises(Exception): # noqa: PT011, B017 + super().test() + class TargetMultipleStateMessages(TargetFileTestTemplate): """Test Target correctly relays multiple received State messages (checkpoints).""" @@ -86,6 +95,13 @@ class TargetRecordBeforeSchemaTest(TargetFileTestTemplate): name = "record_before_schema" + def test(self) -> None: + """Run test.""" + # TODO: the SDK should raise a better error than KeyError in this case + # https://github.com/meltano/sdk/issues/1755 + with pytest.raises(KeyError): + super().test() + class TargetRecordMissingKeyProperty(TargetFileTestTemplate): """Test Target handles record missing key property.""" diff --git a/tests/samples/test_target_parquet.py b/tests/samples/test_target_parquet.py index 5c984679b..7f53036a4 100644 --- a/tests/samples/test_target_parquet.py +++ b/tests/samples/test_target_parquet.py @@ -12,7 +12,9 @@ SAMPLE_FILEPATH = Path(f".output/test_{uuid.uuid4()}/") SAMPLE_FILENAME = SAMPLE_FILEPATH / "testfile.parquet" -SAMPLE_CONFIG = {"filepath": str(SAMPLE_FILENAME)} +SAMPLE_CONFIG = { + "filepath": str(SAMPLE_FILENAME), +} StandardTests = get_target_test_class( target_class=SampleTargetParquet, From 3ceb28a97a77a5e22163fc887fe16ff129c2dc28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 14:46:36 +0000 Subject: [PATCH 19/33] chore(deps-dev): Bump requests-mock from 1.10.0 to 1.11.0 (#1758) --- poetry.lock | 143 +++------------------------------------------------- 1 file changed, 7 insertions(+), 136 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5f6934978..eaad584e1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "alabaster" version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -16,7 +15,6 @@ files = [ name = "appdirs" version = "1.4.4" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" optional = false python-versions = "*" files = [ @@ -28,7 +26,6 @@ files = [ name = "argcomplete" version = "3.0.8" description = "Bash tab completion for argparse" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -46,7 +43,6 @@ test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] name = "arrow" version = "1.2.3" description = "Better dates & times for Python" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -62,7 +58,6 @@ typing-extensions = {version = "*", markers = "python_version < \"3.8\""} name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -84,7 +79,6 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "babel" version = "2.12.1" description = "Internationalization utilities" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -99,7 +93,6 @@ pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} name = "backoff" version = "2.2.1" description = "Function decoration for backoff and retry" -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -111,7 +104,6 @@ files = [ name = "beautifulsoup4" version = "4.12.2" description = "Screen-scraping library" -category = "main" optional = true python-versions = ">=3.6.0" files = [ @@ -130,7 +122,6 @@ lxml = ["lxml"] name = "binaryornot" version = "0.4.4" description = "Ultra-lightweight pure Python package to check if a file is binary or text." -category = "dev" optional = false python-versions = "*" files = [ @@ -145,7 +136,6 @@ chardet = ">=3.0.2" name = "black" version = "23.3.0" description = "The uncompromising code formatter." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -196,7 +186,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "boto3" version = "1.26.129" description = "The AWS SDK for Python" -category = "main" optional = true python-versions = ">= 3.7" files = [ @@ -216,7 +205,6 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] name = "botocore" version = "1.29.129" description = "Low-level, data-driven core of boto 3." -category = "main" optional = true python-versions = ">= 3.7" files = [ @@ -236,7 +224,6 @@ crt = ["awscrt (==0.16.9)"] name = "certifi" version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -248,7 +235,6 @@ files = [ name = "cffi" version = "1.15.1" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = "*" files = [ @@ -325,7 +311,6 @@ pycparser = "*" name = "chardet" version = "5.1.0" description = "Universal encoding detector for Python 3" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -337,7 +322,6 @@ files = [ name = "charset-normalizer" version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -422,7 +406,6 @@ files = [ name = "click" version = "8.1.3" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -438,7 +421,6 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -450,7 +432,6 @@ files = [ name = "commitizen" version = "3.2.1" description = "Python commitizen client tool" -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -476,7 +457,6 @@ typing-extensions = {version = ">=4.0.1,<5.0.0", markers = "python_version < \"3 name = "commitizen-version-bump" version = "0.1.0" description = "Commitizen customized for Meltano projects (https://commitizen-tools.github.io/commitizen/customization)" -category = "dev" optional = false python-versions = "^3.7" files = [] @@ -496,7 +476,6 @@ resolved_reference = "2ac24303b30441773d95357d5c2801275211ce5f" name = "cookiecutter" version = "2.1.1" description = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -517,7 +496,6 @@ requests = ">=2.23.0" name = "coverage" version = "7.2.7" description = "Code coverage measurement for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -593,7 +571,6 @@ toml = ["tomli"] name = "cryptography" version = "41.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -635,7 +612,6 @@ test-randomorder = ["pytest-randomly"] name = "darglint" version = "1.8.1" description = "A utility for ensuring Google-style docstrings stay up to date with the source code." -category = "dev" optional = false python-versions = ">=3.6,<4.0" files = [ @@ -647,7 +623,6 @@ files = [ name = "decli" version = "0.6.0" description = "Minimal, easy-to-use, declarative cli tool" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -659,7 +634,6 @@ files = [ name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -671,7 +645,6 @@ files = [ name = "deprecated" version = "1.2.13" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -689,7 +662,6 @@ dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version name = "docutils" version = "0.19" description = "Docutils -- Python Documentation Utilities" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -701,7 +673,6 @@ files = [ name = "exceptiongroup" version = "1.1.1" description = "Backport of PEP 654 (exception groups)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -716,7 +687,6 @@ test = ["pytest (>=6)"] name = "flake8" version = "3.9.2" description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -734,7 +704,6 @@ pyflakes = ">=2.3.0,<2.4.0" name = "flake8-annotations" version = "2.9.1" description = "Flake8 Type Annotation Checks" -category = "dev" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -751,7 +720,6 @@ typed-ast = {version = ">=1.4,<2.0", markers = "python_version < \"3.8\""} name = "flake8-docstrings" version = "1.7.0" description = "Extension for flake8 which uses pydocstyle to check docstrings" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -767,7 +735,6 @@ pydocstyle = ">=2.1" name = "freezegun" version = "1.2.2" description = "Let your Python tests travel through time" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -782,7 +749,6 @@ python-dateutil = ">=2.7" name = "fs" version = "2.4.16" description = "Python's filesystem abstraction layer" -category = "main" optional = false python-versions = "*" files = [ @@ -802,7 +768,6 @@ scandir = ["scandir (>=1.5,<2.0)"] name = "fs-s3fs" version = "1.1.1" description = "Amazon S3 filesystem for PyFilesystem2" -category = "main" optional = true python-versions = "*" files = [ @@ -819,7 +784,6 @@ six = ">=1.10,<2.0" name = "furo" version = "2023.3.27" description = "A clean customisable Sphinx documentation theme." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -837,7 +801,6 @@ sphinx-basic-ng = "*" name = "greenlet" version = "2.0.2" description = "Lightweight in-process concurrent programming" -category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" files = [ @@ -911,7 +874,6 @@ test = ["objgraph", "psutil"] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -923,7 +885,6 @@ files = [ name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -935,7 +896,6 @@ files = [ name = "importlib-metadata" version = "4.13.0" description = "Read metadata from Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -956,7 +916,6 @@ testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packag name = "importlib-resources" version = "5.12.0" description = "Read resources from Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -975,7 +934,6 @@ testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-chec name = "inflection" version = "0.5.1" description = "A port of Ruby on Rails inflector to Python" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -987,7 +945,6 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -999,7 +956,6 @@ files = [ name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1017,7 +973,6 @@ i18n = ["Babel (>=2.7)"] name = "jinja2-time" version = "0.2.0" description = "Jinja2 Extension for Dates and Times" -category = "dev" optional = false python-versions = "*" files = [ @@ -1033,7 +988,6 @@ jinja2 = "*" name = "jmespath" version = "1.0.1" description = "JSON Matching Expressions" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1045,7 +999,6 @@ files = [ name = "joblib" version = "1.2.0" description = "Lightweight pipelining with Python functions" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1057,7 +1010,6 @@ files = [ name = "jsonpath-ng" version = "1.5.3" description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." -category = "main" optional = false python-versions = "*" files = [ @@ -1075,7 +1027,6 @@ six = "*" name = "jsonschema" version = "4.17.3" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1099,7 +1050,6 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "livereload" version = "2.6.3" description = "Python LiveReload is an awesome tool for web developers" -category = "main" optional = true python-versions = "*" files = [ @@ -1115,7 +1065,6 @@ tornado = {version = "*", markers = "python_version > \"2.7\""} name = "markdown-it-py" version = "2.2.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1141,7 +1090,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markupsafe" version = "2.1.2" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1201,7 +1149,6 @@ files = [ name = "mccabe" version = "0.6.1" description = "McCabe checker, plugin for flake8" -category = "dev" optional = false python-versions = "*" files = [ @@ -1213,7 +1160,6 @@ files = [ name = "mdit-py-plugins" version = "0.3.5" description = "Collection of plugins for markdown-it-py" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1233,7 +1179,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1245,7 +1190,6 @@ files = [ name = "memoization" version = "0.4.0" description = "A powerful caching library for Python, with TTL support and multiple algorithm options. (https://github.com/lonelyenvoy/python-memoization)" -category = "main" optional = false python-versions = ">=3, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4" files = [ @@ -1256,7 +1200,6 @@ files = [ name = "mypy" version = "1.3.0" description = "Optional static typing for Python" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1304,7 +1247,6 @@ reports = ["lxml"] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1316,7 +1258,6 @@ files = [ name = "myst-parser" version = "1.0.0" description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1344,7 +1285,6 @@ testing-docutils = ["pygments", "pytest (>=7,<8)", "pytest-param-files (>=0.3.4, name = "numpy" version = "1.21.6" description = "NumPy is the fundamental package for array computing with Python." -category = "dev" optional = false python-versions = ">=3.7,<3.11" files = [ @@ -1385,7 +1325,6 @@ files = [ name = "numpy" version = "1.24.3" description = "Fundamental package for array computing in Python" -category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1423,7 +1362,6 @@ files = [ name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1435,7 +1373,6 @@ files = [ name = "pathspec" version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1447,7 +1384,6 @@ files = [ name = "pendulum" version = "2.1.2" description = "Python datetimes made easy" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1482,7 +1418,6 @@ pytzdata = ">=2020.1" name = "pkgutil-resolve-name" version = "1.3.10" description = "Resolve a name to an object." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1494,7 +1429,6 @@ files = [ name = "platformdirs" version = "3.5.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1513,7 +1447,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest- name = "pluggy" version = "1.0.0" description = "plugin and hook calling mechanisms for python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1532,7 +1465,6 @@ testing = ["pytest", "pytest-benchmark"] name = "ply" version = "3.11" description = "Python Lex & Yacc" -category = "main" optional = false python-versions = "*" files = [ @@ -1544,7 +1476,6 @@ files = [ name = "prompt-toolkit" version = "3.0.38" description = "Library for building powerful interactive command lines in Python" -category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -1559,7 +1490,6 @@ wcwidth = "*" name = "pyarrow" version = "12.0.0" description = "Python library for Apache Arrow" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1597,7 +1527,6 @@ numpy = ">=1.16.6" name = "pycodestyle" version = "2.7.0" description = "Python style guide checker" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1609,7 +1538,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1621,7 +1549,6 @@ files = [ name = "pydocstyle" version = "6.3.0" description = "Python docstring style checker" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1640,7 +1567,6 @@ toml = ["tomli (>=1.2.3)"] name = "pyflakes" version = "2.3.1" description = "passive checker of Python programs" -category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1652,7 +1578,6 @@ files = [ name = "pygithub" version = "1.58.1" description = "Use the full Github API v3" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1670,7 +1595,6 @@ requests = ">=2.14.0" name = "pygments" version = "2.15.1" description = "Pygments is a syntax highlighting package written in Python." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -1685,7 +1609,6 @@ plugins = ["importlib-metadata"] name = "pyjwt" version = "2.7.0" description = "JSON Web Token implementation in Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1707,7 +1630,6 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] name = "pynacl" version = "1.5.0" description = "Python binding to the Networking and Cryptography (NaCl) library" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1734,7 +1656,6 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"] name = "pyrsistent" version = "0.19.3" description = "Persistent/Functional/Immutable data structures" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1771,7 +1692,6 @@ files = [ name = "pytest" version = "7.3.1" description = "pytest: simple powerful testing with Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1795,7 +1715,6 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-durations" version = "1.2.0" description = "Pytest plugin reporting fixtures and test functions execution time." -category = "main" optional = true python-versions = ">=3.6.2" files = [ @@ -1810,7 +1729,6 @@ pytest = ">=4.6" name = "pytest-snapshot" version = "0.9.0" description = "A plugin for snapshot testing with pytest." -category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1825,7 +1743,6 @@ pytest = ">=3.0.0" name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -1840,7 +1757,6 @@ six = ">=1.5" name = "python-dotenv" version = "0.21.1" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1855,7 +1771,6 @@ cli = ["click (>=5.0)"] name = "python-slugify" version = "8.0.1" description = "A Python slugify application that also handles Unicode" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1873,7 +1788,6 @@ unidecode = ["Unidecode (>=1.1.1)"] name = "pytz" version = "2023.3" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" files = [ @@ -1885,7 +1799,6 @@ files = [ name = "pytzdata" version = "2020.1" description = "The Olson timezone database for Python." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1897,7 +1810,6 @@ files = [ name = "pyyaml" version = "6.0" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1947,7 +1859,6 @@ files = [ name = "questionary" version = "1.10.0" description = "Python library to build pretty command line user prompts ⭐️" -category = "dev" optional = false python-versions = ">=3.6,<4.0" files = [ @@ -1965,7 +1876,6 @@ docs = ["Sphinx (>=3.3,<4.0)", "sphinx-autobuild (>=2020.9.1,<2021.0.0)", "sphin name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1985,14 +1895,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "requests-mock" -version = "1.10.0" +version = "1.11.0" description = "Mock out responses from the requests package" -category = "dev" optional = false python-versions = "*" files = [ - {file = "requests-mock-1.10.0.tar.gz", hash = "sha256:59c9c32419a9fb1ae83ec242d98e889c45bd7d7a65d48375cc243ec08441658b"}, - {file = "requests_mock-1.10.0-py2.py3-none-any.whl", hash = "sha256:2fdbb637ad17ee15c06f33d31169e71bf9fe2bdb7bc9da26185be0dd8d842699"}, + {file = "requests-mock-1.11.0.tar.gz", hash = "sha256:ef10b572b489a5f28e09b708697208c4a3b2b89ef80a9f01584340ea357ec3c4"}, + {file = "requests_mock-1.11.0-py2.py3-none-any.whl", hash = "sha256:f7fae383f228633f6bececebdab236c478ace2284d6292c6e7e2867b9ab74d15"}, ] [package.dependencies] @@ -2001,13 +1910,12 @@ six = "*" [package.extras] fixture = ["fixtures"] -test = ["fixtures", "mock", "purl", "pytest", "requests-futures", "sphinx", "testrepository (>=0.0.18)", "testtools"] +test = ["fixtures", "mock", "purl", "pytest", "requests-futures", "sphinx", "testtools"] [[package]] name = "s3transfer" version = "0.6.1" description = "An Amazon S3 Transfer Manager" -category = "main" optional = true python-versions = ">= 3.7" files = [ @@ -2025,7 +1933,6 @@ crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] name = "setuptools" version = "67.7.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2042,7 +1949,6 @@ testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs ( name = "simplejson" version = "3.19.1" description = "Simple, fast, extensible JSON encoder/decoder for Python" -category = "main" optional = false python-versions = ">=2.5, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2137,7 +2043,6 @@ files = [ name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2149,7 +2054,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "main" optional = false python-versions = "*" files = [ @@ -2161,7 +2065,6 @@ files = [ name = "soupsieve" version = "2.4.1" description = "A modern CSS selector implementation for Beautiful Soup." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -2173,7 +2076,6 @@ files = [ name = "sphinx" version = "5.3.0" description = "Python documentation generator" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -2209,7 +2111,6 @@ test = ["cython", "html5lib", "pytest (>=4.6)", "typed_ast"] name = "sphinx-autobuild" version = "2021.3.14" description = "Rebuild Sphinx documentation on changes, with live-reload in the browser." -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -2229,7 +2130,6 @@ test = ["pytest", "pytest-cov"] name = "sphinx-basic-ng" version = "1.0.0b1" description = "A modern skeleton for Sphinx themes." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -2247,7 +2147,6 @@ docs = ["furo", "ipython", "myst-parser", "sphinx-copybutton", "sphinx-inline-ta name = "sphinx-copybutton" version = "0.5.2" description = "Add a copy button to each of your code cells." -category = "main" optional = true python-versions = ">=3.7" files = [ @@ -2266,7 +2165,6 @@ rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] name = "sphinx-reredirects" version = "0.1.2" description = "Handles redirects for moved pages in Sphinx documentation projects" -category = "main" optional = true python-versions = ">=3.5" files = [ @@ -2281,7 +2179,6 @@ sphinx = "*" name = "sphinxcontrib-applehelp" version = "1.0.2" description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" -category = "main" optional = true python-versions = ">=3.5" files = [ @@ -2297,7 +2194,6 @@ test = ["pytest"] name = "sphinxcontrib-devhelp" version = "1.0.2" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." -category = "main" optional = true python-versions = ">=3.5" files = [ @@ -2313,7 +2209,6 @@ test = ["pytest"] name = "sphinxcontrib-htmlhelp" version = "2.0.0" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "main" optional = true python-versions = ">=3.6" files = [ @@ -2329,7 +2224,6 @@ test = ["html5lib", "pytest"] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "main" optional = true python-versions = ">=3.5" files = [ @@ -2344,7 +2238,6 @@ test = ["flake8", "mypy", "pytest"] name = "sphinxcontrib-qthelp" version = "1.0.3" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." -category = "main" optional = true python-versions = ">=3.5" files = [ @@ -2360,7 +2253,6 @@ test = ["pytest"] name = "sphinxcontrib-serializinghtml" version = "1.1.5" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." -category = "main" optional = true python-versions = ">=3.5" files = [ @@ -2376,7 +2268,6 @@ test = ["pytest"] name = "sqlalchemy" version = "1.4.48" description = "Database Abstraction Library" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -2424,7 +2315,7 @@ files = [ ] [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} +greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\")"} importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [package.extras] @@ -2452,7 +2343,6 @@ sqlcipher = ["sqlcipher3-binary"] name = "sqlalchemy2-stubs" version = "0.0.2a34" description = "Typing Stubs for SQLAlchemy 1.4" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2467,7 +2357,6 @@ typing-extensions = ">=3.7.4" name = "termcolor" version = "2.3.0" description = "ANSI color formatting for output in terminal" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2482,7 +2371,6 @@ tests = ["pytest", "pytest-cov"] name = "text-unidecode" version = "1.3" description = "The most basic Text::Unidecode port" -category = "dev" optional = false python-versions = "*" files = [ @@ -2494,7 +2382,6 @@ files = [ name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2506,7 +2393,6 @@ files = [ name = "tomlkit" version = "0.11.8" description = "Style preserving TOML library" -category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2518,7 +2404,6 @@ files = [ name = "tornado" version = "6.2" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "main" optional = true python-versions = ">= 3.7" files = [ @@ -2539,7 +2424,6 @@ files = [ name = "typed-ast" version = "1.5.4" description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2573,7 +2457,6 @@ files = [ name = "types-jsonschema" version = "4.17.0.8" description = "Typing stubs for jsonschema" -category = "dev" optional = false python-versions = "*" files = [ @@ -2585,7 +2468,6 @@ files = [ name = "types-python-dateutil" version = "2.8.19.13" description = "Typing stubs for python-dateutil" -category = "dev" optional = false python-versions = "*" files = [ @@ -2597,7 +2479,6 @@ files = [ name = "types-pytz" version = "2023.3.0.0" description = "Typing stubs for pytz" -category = "dev" optional = false python-versions = "*" files = [ @@ -2609,7 +2490,6 @@ files = [ name = "types-pyyaml" version = "6.0.12.10" description = "Typing stubs for PyYAML" -category = "dev" optional = false python-versions = "*" files = [ @@ -2621,7 +2501,6 @@ files = [ name = "types-requests" version = "2.31.0.1" description = "Typing stubs for requests" -category = "dev" optional = false python-versions = "*" files = [ @@ -2636,7 +2515,6 @@ types-urllib3 = "*" name = "types-simplejson" version = "3.19.0.1" description = "Typing stubs for simplejson" -category = "dev" optional = false python-versions = "*" files = [ @@ -2648,7 +2526,6 @@ files = [ name = "types-urllib3" version = "1.26.25.12" description = "Typing stubs for urllib3" -category = "dev" optional = false python-versions = "*" files = [ @@ -2660,7 +2537,6 @@ files = [ name = "typing-extensions" version = "4.6.3" description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2672,7 +2548,6 @@ files = [ name = "urllib3" version = "1.26.15" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -2689,7 +2564,6 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "wcwidth" version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" -category = "dev" optional = false python-versions = "*" files = [ @@ -2701,7 +2575,6 @@ files = [ name = "wrapt" version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." -category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" files = [ @@ -2786,7 +2659,6 @@ files = [ name = "xdoctest" version = "1.1.1" description = "A rewrite of the builtin doctest module" -category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -2814,7 +2686,6 @@ tests-strict = ["codecov (==2.0.15)", "pytest (==4.6.0)", "pytest (==4.6.0)", "p name = "zipp" version = "3.15.0" description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2827,7 +2698,7 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [extras] -docs = ["sphinx", "furo", "sphinx-copybutton", "myst-parser", "sphinx-autobuild", "sphinx-reredirects"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-autobuild", "sphinx-copybutton", "sphinx-reredirects"] s3 = ["fs-s3fs"] testing = ["pytest", "pytest-durations"] From 0cf280be1378caaadde45cad00292f644bed88dd Mon Sep 17 00:00:00 2001 From: Ken Payne Date: Fri, 16 Jun 2023 12:29:05 +0100 Subject: [PATCH 20/33] chore: add tests to issue template options (#1764) --- .github/ISSUE_TEMPLATE/feature.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature.yml b/.github/ISSUE_TEMPLATE/feature.yml index ad08d3e6a..a5afd5974 100644 --- a/.github/ISSUE_TEMPLATE/feature.yml +++ b/.github/ISSUE_TEMPLATE/feature.yml @@ -16,8 +16,8 @@ body: label: Feature scope description: Functionality this new feature would impact options: - - Taps (catalog, state, stream maps, etc.) - - Targets (data type handling, batching, SQL object generation, etc.) + - Taps (catalog, state, stream maps, tests, etc.) + - Targets (data type handling, batching, SQL object generation, tests, etc.) - Configuration (settings parsing, validation, etc.) - CLI (options, error messages, logging, etc.) - Cookiecutter templates From b49804265844d88eafafb80163d971cc1a7054eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 13:23:16 +0000 Subject: [PATCH 21/33] chore(deps): Bump pytest from 7.3.1 to 7.3.2 (#1766) --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index eaad584e1..7fab94625 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1690,13 +1690,13 @@ files = [ [[package]] name = "pytest" -version = "7.3.1" +version = "7.3.2" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.3.1-py3-none-any.whl", hash = "sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"}, - {file = "pytest-7.3.1.tar.gz", hash = "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"}, + {file = "pytest-7.3.2-py3-none-any.whl", hash = "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295"}, + {file = "pytest-7.3.2.tar.gz", hash = "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b"}, ] [package.dependencies] @@ -1709,7 +1709,7 @@ pluggy = ">=0.12,<2.0" tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-durations" From d7a1e79f9d0c27f9356b5d5b0859b1a05d00e32e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 14:10:40 +0000 Subject: [PATCH 22/33] chore(deps): Bump actions/checkout from 3.5.2 to 3.5.3 (#1759) --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/cookiecutter-e2e.yml | 2 +- .github/workflows/dependency-review.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 6 +++--- .github/workflows/version_bump.yml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0dbb8bc22..75b4dc276 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -31,7 +31,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/cookiecutter-e2e.yml b/.github/workflows/cookiecutter-e2e.yml index 766857ac0..7adca51d7 100644 --- a/.github/workflows/cookiecutter-e2e.yml +++ b/.github/workflows/cookiecutter-e2e.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Check out the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Upgrade pip env: diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index dc7c94bbd..8048f9cad 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: GitHub dependency vulnerability check if: ${{ github.event_name == 'pull_request_target' }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 35d1db076..f34a699f3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Set up Python uses: actions/setup-python@v4.6.1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ed83c627f..150901c93 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: steps: - name: Check out the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Install Poetry env: @@ -91,7 +91,7 @@ jobs: steps: - name: Check out the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Install Poetry env: @@ -133,7 +133,7 @@ jobs: needs: tests steps: - name: Check out the repository - uses: actions/checkout@v3.5.2 + uses: actions/checkout@v3.5.3 - name: Install Poetry run: | diff --git a/.github/workflows/version_bump.yml b/.github/workflows/version_bump.yml index 1889fcf22..47649408e 100644 --- a/.github/workflows/version_bump.yml +++ b/.github/workflows/version_bump.yml @@ -35,7 +35,7 @@ jobs: pull-requests: write # to create and update PRs steps: - - uses: actions/checkout@v3.5.2 + - uses: actions/checkout@v3.5.3 with: fetch-depth: 0 From e8772158aa7b4a0f87fb280d40bba68f8c0e72e3 Mon Sep 17 00:00:00 2001 From: Pat Nadolny Date: Mon, 19 Jun 2023 10:49:12 -0400 Subject: [PATCH 23/33] fix: Add descriptions for `batch_config` properties (#1771) add descriptions for batch_config properties --- singer_sdk/helpers/capabilities.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/singer_sdk/helpers/capabilities.py b/singer_sdk/helpers/capabilities.py index 00a420daf..55aff8ce3 100644 --- a/singer_sdk/helpers/capabilities.py +++ b/singer_sdk/helpers/capabilities.py @@ -59,11 +59,17 @@ "encoding", description="Specifies the format and compression of the batch files.", wrapped=ObjectType( - Property("format", StringType, allowed_values=["jsonl"]), + Property( + "format", + StringType, + allowed_values=["jsonl"], + description="Format to use for batch files.", + ), Property( "compression", StringType, allowed_values=["gzip", "none"], + description="Compression format to use for batch files.", ), ), ), @@ -71,8 +77,16 @@ "storage", description="Defines the storage layer to use when writing batch files", wrapped=ObjectType( - Property("root", StringType), - Property("prefix", StringType), + Property( + "root", + StringType, + description="Root path to use when writing batch files.", + ), + Property( + "prefix", + StringType, + description="Prefix to use when writing batch files.", + ), ), ), ), From 7e8997f9fdd1185984db99cfaeab64b278b2252e Mon Sep 17 00:00:00 2001 From: Pat Nadolny Date: Mon, 19 Jun 2023 16:21:50 -0400 Subject: [PATCH 24/33] fix: Add tests for SQL type conversion from JSON schemas (#1775) * add tests for sql type parsing * fix anyof sqltype parsing test * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * cleanup precommit errors * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update imports in tests --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- singer_sdk/typing.py | 4 +++- tests/core/test_typing.py | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/singer_sdk/typing.py b/singer_sdk/typing.py index f2766944c..1e70f6201 100644 --- a/singer_sdk/typing.py +++ b/singer_sdk/typing.py @@ -825,7 +825,9 @@ def _jsonschema_type_check(jsonschema_type: dict, type_check: tuple[str]) -> boo if jsonschema_type.get("type") in type_check: # noqa: PLR5501 return True - if any(t in type_check for t in jsonschema_type.get("anyOf", ())): + if any( + _jsonschema_type_check(t, type_check) for t in jsonschema_type.get("anyOf", ()) + ): return True return False diff --git a/tests/core/test_typing.py b/tests/core/test_typing.py index 854669e5b..b2cf9c691 100644 --- a/tests/core/test_typing.py +++ b/tests/core/test_typing.py @@ -4,7 +4,9 @@ import datetime import logging -import typing as t + +import pytest +import sqlalchemy from singer_sdk.helpers._typing import ( TypeConformanceLevel, @@ -17,11 +19,9 @@ PropertiesList, Property, StringType, + to_sql_type, ) -if t.TYPE_CHECKING: - import pytest - logger = logging.getLogger("log") @@ -292,3 +292,29 @@ def test_conform_primitives(): assert _conform_primitive_property(None, {"type": "boolean"}) is None assert _conform_primitive_property(0, {"type": "boolean"}) is False assert _conform_primitive_property(1, {"type": "boolean"}) is True + + +@pytest.mark.parametrize( + "jsonschema_type,expected", + [ + ({"type": ["string", "null"]}, sqlalchemy.types.VARCHAR), + ({"type": ["integer", "null"]}, sqlalchemy.types.INTEGER), + ({"type": ["number", "null"]}, sqlalchemy.types.DECIMAL), + ({"type": ["boolean", "null"]}, sqlalchemy.types.BOOLEAN), + ({"type": "object", "properties": {}}, sqlalchemy.types.VARCHAR), + ({"type": "array"}, sqlalchemy.types.VARCHAR), + ({"format": "date", "type": ["string", "null"]}, sqlalchemy.types.DATE), + ({"format": "time", "type": ["string", "null"]}, sqlalchemy.types.TIME), + ( + {"format": "date-time", "type": ["string", "null"]}, + sqlalchemy.types.DATETIME, + ), + ( + {"anyOf": [{"type": "string", "format": "date-time"}, {"type": "null"}]}, + sqlalchemy.types.DATETIME, + ), + ({"anyOf": [{"type": "integer"}, {"type": "null"}]}, sqlalchemy.types.INTEGER), + ], +) +def test_to_sql_type(jsonschema_type, expected): + assert isinstance(to_sql_type(jsonschema_type), expected) From e2be08152ecd8709979571479646f2d262f8ac6a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 16:48:02 -0600 Subject: [PATCH 25/33] chore: pre-commit autoupdate (#1760) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: pre-commit autoupdate updates: - [github.com/charliermarsh/ruff-pre-commit: v0.0.270 → v0.0.272](https://github.com/charliermarsh/ruff-pre-commit/compare/v0.0.270...v0.0.272) * Use sequences instead of sets to iterate --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Edgar R. M Co-authored-by: Edgar Ramírez Mondragón --- .pre-commit-config.yaml | 2 +- singer_sdk/sinks/core.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3b4bcc315..03fb5f67d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,7 +43,7 @@ repos: - id: check-readthedocs - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.270 + rev: v0.0.272 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/singer_sdk/sinks/core.py b/singer_sdk/sinks/core.py index 0c6351779..fbcbbb295 100644 --- a/singer_sdk/sinks/core.py +++ b/singer_sdk/sinks/core.py @@ -254,17 +254,17 @@ def _add_sdc_metadata_to_schema(self) -> None: https://sdk.meltano.com/en/latest/implementation/record_metadata.html """ properties_dict = self.schema["properties"] - for col in { + for col in ( "_sdc_extracted_at", "_sdc_received_at", "_sdc_batched_at", "_sdc_deleted_at", - }: + ): properties_dict[col] = { "type": ["null", "string"], "format": "date-time", } - for col in {"_sdc_sequence", "_sdc_table_version"}: + for col in ("_sdc_sequence", "_sdc_table_version"): properties_dict[col] = {"type": ["null", "integer"]} def _remove_sdc_metadata_from_schema(self) -> None: @@ -274,14 +274,14 @@ def _remove_sdc_metadata_from_schema(self) -> None: https://sdk.meltano.com/en/latest/implementation/record_metadata.html """ properties_dict = self.schema["properties"] - for col in { + for col in ( "_sdc_extracted_at", "_sdc_received_at", "_sdc_batched_at", "_sdc_deleted_at", "_sdc_sequence", "_sdc_table_version", - }: + ): properties_dict.pop(col, None) def _remove_sdc_metadata_from_record(self, record: dict) -> None: From 56c794fd599c501e794ad964b95b2459f3b5dc52 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 16:57:15 -0600 Subject: [PATCH 26/33] chore(deps-dev): Bump pyarrow from 12.0.0 to 12.0.1 (#1762) Bumps [pyarrow](https://github.com/apache/arrow) from 12.0.0 to 12.0.1. - [Commits](https://github.com/apache/arrow/compare/go/v12.0.0...go/v12.0.1) --- updated-dependencies: - dependency-name: pyarrow dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7fab94625..363130529 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1488,36 +1488,36 @@ wcwidth = "*" [[package]] name = "pyarrow" -version = "12.0.0" +version = "12.0.1" description = "Python library for Apache Arrow" optional = false python-versions = ">=3.7" files = [ - {file = "pyarrow-12.0.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:3b97649c8a9a09e1d8dc76513054f1331bd9ece78ee39365e6bf6bc7503c1e94"}, - {file = "pyarrow-12.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bc4ea634dacb03936f50fcf59574a8e727f90c17c24527e488d8ceb52ae284de"}, - {file = "pyarrow-12.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d568acfca3faa565d663e53ee34173be8e23a95f78f2abfdad198010ec8f745"}, - {file = "pyarrow-12.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b50bb9a82dca38a002d7cbd802a16b1af0f8c50ed2ec94a319f5f2afc047ee9"}, - {file = "pyarrow-12.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:3d1733b1ea086b3c101427d0e57e2be3eb964686e83c2363862a887bb5c41fa8"}, - {file = "pyarrow-12.0.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:a7cd32fe77f967fe08228bc100433273020e58dd6caced12627bcc0a7675a513"}, - {file = "pyarrow-12.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:92fb031e6777847f5c9b01eaa5aa0c9033e853ee80117dce895f116d8b0c3ca3"}, - {file = "pyarrow-12.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:280289ebfd4ac3570f6b776515baa01e4dcbf17122c401e4b7170a27c4be63fd"}, - {file = "pyarrow-12.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:272f147d4f8387bec95f17bb58dcfc7bc7278bb93e01cb7b08a0e93a8921e18e"}, - {file = "pyarrow-12.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:0846ace49998825eda4722f8d7f83fa05601c832549c9087ea49d6d5397d8cec"}, - {file = "pyarrow-12.0.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:993287136369aca60005ee7d64130f9466489c4f7425f5c284315b0a5401ccd9"}, - {file = "pyarrow-12.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a7b6a765ee4f88efd7d8348d9a1f804487d60799d0428b6ddf3344eaef37282"}, - {file = "pyarrow-12.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c4fce253d5bdc8d62f11cfa3da5b0b34b562c04ce84abb8bd7447e63c2b327"}, - {file = "pyarrow-12.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e6be4d85707fc8e7a221c8ab86a40449ce62559ce25c94321df7c8500245888f"}, - {file = "pyarrow-12.0.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:ea830d9f66bfb82d30b5794642f83dd0e4a718846462d22328981e9eb149cba8"}, - {file = "pyarrow-12.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7b5b9f60d9ef756db59bec8d90e4576b7df57861e6a3d6a8bf99538f68ca15b3"}, - {file = "pyarrow-12.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b99e559d27db36ad3a33868a475f03e3129430fc065accc839ef4daa12c6dab6"}, - {file = "pyarrow-12.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b0810864a593b89877120972d1f7af1d1c9389876dbed92b962ed81492d3ffc"}, - {file = "pyarrow-12.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:23a77d97f4d101ddfe81b9c2ee03a177f0e590a7e68af15eafa06e8f3cf05976"}, - {file = "pyarrow-12.0.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:2cc63e746221cddb9001f7281dee95fd658085dd5b717b076950e1ccc607059c"}, - {file = "pyarrow-12.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d8c26912607e26c2991826bbaf3cf2b9c8c3e17566598c193b492f058b40d3a4"}, - {file = "pyarrow-12.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d8b90efc290e99a81d06015f3a46601c259ecc81ffb6d8ce288c91bd1b868c9"}, - {file = "pyarrow-12.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2466be046b81863be24db370dffd30a2e7894b4f9823fb60ef0a733c31ac6256"}, - {file = "pyarrow-12.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:0e36425b1c1cbf5447718b3f1751bf86c58f2b3ad299f996cd9b1aa040967656"}, - {file = "pyarrow-12.0.0.tar.gz", hash = "sha256:19c812d303610ab5d664b7b1de4051ae23565f9f94d04cbea9e50569746ae1ee"}, + {file = "pyarrow-12.0.1-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:6d288029a94a9bb5407ceebdd7110ba398a00412c5b0155ee9813a40d246c5df"}, + {file = "pyarrow-12.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345e1828efdbd9aa4d4de7d5676778aba384a2c3add896d995b23d368e60e5af"}, + {file = "pyarrow-12.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d6009fdf8986332b2169314da482baed47ac053311c8934ac6651e614deacd6"}, + {file = "pyarrow-12.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d3c4cbbf81e6dd23fe921bc91dc4619ea3b79bc58ef10bce0f49bdafb103daf"}, + {file = "pyarrow-12.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:cdacf515ec276709ac8042c7d9bd5be83b4f5f39c6c037a17a60d7ebfd92c890"}, + {file = "pyarrow-12.0.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:749be7fd2ff260683f9cc739cb862fb11be376de965a2a8ccbf2693b098db6c7"}, + {file = "pyarrow-12.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6895b5fb74289d055c43db3af0de6e16b07586c45763cb5e558d38b86a91e3a7"}, + {file = "pyarrow-12.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1887bdae17ec3b4c046fcf19951e71b6a619f39fa674f9881216173566c8f718"}, + {file = "pyarrow-12.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2c9cb8eeabbadf5fcfc3d1ddea616c7ce893db2ce4dcef0ac13b099ad7ca082"}, + {file = "pyarrow-12.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:ce4aebdf412bd0eeb800d8e47db854f9f9f7e2f5a0220440acf219ddfddd4f63"}, + {file = "pyarrow-12.0.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:e0d8730c7f6e893f6db5d5b86eda42c0a130842d101992b581e2138e4d5663d3"}, + {file = "pyarrow-12.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43364daec02f69fec89d2315f7fbfbeec956e0d991cbbef471681bd77875c40f"}, + {file = "pyarrow-12.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:051f9f5ccf585f12d7de836e50965b3c235542cc896959320d9776ab93f3b33d"}, + {file = "pyarrow-12.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:be2757e9275875d2a9c6e6052ac7957fbbfc7bc7370e4a036a9b893e96fedaba"}, + {file = "pyarrow-12.0.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:cf812306d66f40f69e684300f7af5111c11f6e0d89d6b733e05a3de44961529d"}, + {file = "pyarrow-12.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:459a1c0ed2d68671188b2118c63bac91eaef6fc150c77ddd8a583e3c795737bf"}, + {file = "pyarrow-12.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85e705e33eaf666bbe508a16fd5ba27ca061e177916b7a317ba5a51bee43384c"}, + {file = "pyarrow-12.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9120c3eb2b1f6f516a3b7a9714ed860882d9ef98c4b17edcdc91d95b7528db60"}, + {file = "pyarrow-12.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:c780f4dc40460015d80fcd6a6140de80b615349ed68ef9adb653fe351778c9b3"}, + {file = "pyarrow-12.0.1-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:a3c63124fc26bf5f95f508f5d04e1ece8cc23a8b0af2a1e6ab2b1ec3fdc91b24"}, + {file = "pyarrow-12.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b13329f79fa4472324f8d32dc1b1216616d09bd1e77cfb13104dec5463632c36"}, + {file = "pyarrow-12.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb656150d3d12ec1396f6dde542db1675a95c0cc8366d507347b0beed96e87ca"}, + {file = "pyarrow-12.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6251e38470da97a5b2e00de5c6a049149f7b2bd62f12fa5dbb9ac674119ba71a"}, + {file = "pyarrow-12.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:3de26da901216149ce086920547dfff5cd22818c9eab67ebc41e863a5883bac7"}, + {file = "pyarrow-12.0.1.tar.gz", hash = "sha256:cce317fc96e5b71107bf1f9f184d5e54e2bd14bbf3f9a3d62819961f0af86fec"}, ] [package.dependencies] From 5a5f43a4fb43f55412464fa816cde70f4198607b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 23:14:25 +0000 Subject: [PATCH 27/33] chore(deps): Bump pre-commit from 3.3.2 to 3.3.3 in /.github/workflows (#1761) --- .github/workflows/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt index 6596d2c0e..01217f3a3 100644 --- a/.github/workflows/constraints.txt +++ b/.github/workflows/constraints.txt @@ -1,5 +1,5 @@ pip==23.1.2 poetry==1.5.1 -pre-commit==3.3.2 +pre-commit==3.3.3 nox==2023.4.22 nox-poetry==1.0.2 From 3e7f5b3d121295de0bea22fc2ce9b56b882b7432 Mon Sep 17 00:00:00 2001 From: "Edgar R. M" Date: Mon, 19 Jun 2023 17:59:09 -0600 Subject: [PATCH 28/33] fix: Force stream selection in tests (#1698) Co-authored-by: Ken Payne --- singer_sdk/streams/core.py | 11 +++++++++- singer_sdk/tap_base.py | 4 ++++ tests/samples/test_tap_countries.py | 22 +++++++++++++++++++ .../countries_write_schemas | 2 ++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/snapshots/countries_write_schemas/countries_write_schemas diff --git a/singer_sdk/streams/core.py b/singer_sdk/streams/core.py index 31e16dc8b..a414123dd 100644 --- a/singer_sdk/streams/core.py +++ b/singer_sdk/streams/core.py @@ -269,7 +269,6 @@ def get_starting_timestamp(self, context: dict | None) -> datetime.datetime | No return t.cast(datetime.datetime, pendulum.parse(value)) - @final @property def selected(self) -> bool: """Check if stream is selected. @@ -279,6 +278,16 @@ def selected(self) -> bool: """ return self.mask.get((), True) + @selected.setter + def selected(self, value: bool | None) -> None: + """Set stream selection. + + Args: + value: True if the stream is selected. + """ + self.metadata.root.selected = value + self._mask = self.metadata.resolve_selection() + @final @property def has_selected_descendents(self) -> bool: diff --git a/singer_sdk/tap_base.py b/singer_sdk/tap_base.py index 23d8e815b..150f0ee81 100644 --- a/singer_sdk/tap_base.py +++ b/singer_sdk/tap_base.py @@ -246,6 +246,9 @@ def run_sync_dry_run( # Initialize streams' record limits before beginning the sync test. stream.ABORT_AT_RECORD_COUNT = dry_run_record_limit + # Force selection of streams. + stream.selected = True + for stream in streams: if stream.parent_stream_type: self.logger.debug( @@ -267,6 +270,7 @@ def run_sync_dry_run( def write_schemas(self) -> None: """Write a SCHEMA message for all known streams to STDOUT.""" for stream in self.streams.values(): + stream.selected = True stream._write_schema_message() # Stream detection: diff --git a/tests/samples/test_tap_countries.py b/tests/samples/test_tap_countries.py index f822f5c8b..e1910d0cb 100644 --- a/tests/samples/test_tap_countries.py +++ b/tests/samples/test_tap_countries.py @@ -9,6 +9,9 @@ import typing as t from contextlib import redirect_stdout +import pytest +from click.testing import CliRunner + from samples.sample_tap_countries.countries_tap import SampleTapCountries from singer_sdk.helpers._catalog import ( get_selected_schema, @@ -17,6 +20,11 @@ from singer_sdk.testing import get_tap_test_class from singer_sdk.testing.config import SuiteConfig +if t.TYPE_CHECKING: + from pathlib import Path + + from pytest_snapshot.plugin import Snapshot + SAMPLE_CONFIG = {} SAMPLE_CONFIG_BAD = {"not": "correct"} @@ -136,3 +144,17 @@ def tally_messages(messages: list) -> t.Counter: assert counter["BATCH", "countries"] == 1 assert counter[("STATE",)] == 3 + + +@pytest.mark.snapshot() +def test_write_schema( + snapshot: Snapshot, + snapshot_dir: Path, +): + snapshot.snapshot_dir = snapshot_dir.joinpath("countries_write_schemas") + + runner = CliRunner(mix_stderr=False) + result = runner.invoke(SampleTapCountries.cli, ["--test", "schema"]) + + snapshot_name = "countries_write_schemas" + snapshot.assert_match(result.stdout, snapshot_name) diff --git a/tests/snapshots/countries_write_schemas/countries_write_schemas b/tests/snapshots/countries_write_schemas/countries_write_schemas new file mode 100644 index 000000000..b0808ce23 --- /dev/null +++ b/tests/snapshots/countries_write_schemas/countries_write_schemas @@ -0,0 +1,2 @@ +{"type": "SCHEMA", "stream": "continents", "schema": {"properties": {"code": {"type": ["null", "string"]}, "name": {"type": ["null", "string"]}}, "type": "object"}, "key_properties": ["code"]} +{"type": "SCHEMA", "stream": "countries", "schema": {"properties": {"code": {"type": ["string", "null"]}, "name": {"type": ["string", "null"]}, "native": {"type": ["string", "null"]}, "phone": {"type": ["string", "null"]}, "capital": {"type": ["string", "null"]}, "currency": {"type": ["string", "null"]}, "emoji": {"type": ["string", "null"]}, "continent": {"properties": {"code": {"type": ["string", "null"]}, "name": {"type": ["string", "null"]}}, "type": ["object", "null"]}, "languages": {"items": {"properties": {"code": {"type": ["string", "null"]}, "name": {"type": ["string", "null"]}}, "type": "object"}, "type": ["array", "null"]}}, "type": "object"}, "key_properties": ["code"]} From bd1a425fe97ba78adf64f600b1e4071a081fe82b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 06:31:49 -0600 Subject: [PATCH 29/33] chore: pre-commit autoupdate (#1776) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/python-jsonschema/check-jsonschema: 0.23.1 → 0.23.2](https://github.com/python-jsonschema/check-jsonschema/compare/0.23.1...0.23.2) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .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 03fb5f67d..6ba7d32d6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: )$ - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.23.1 + rev: 0.23.2 hooks: - id: check-dependabot - id: check-github-workflows From 88d7586e538a0a38547757e11a8347ef6dd93ac0 Mon Sep 17 00:00:00 2001 From: "Taylor A. Murphy" Date: Tue, 20 Jun 2023 10:22:38 -0500 Subject: [PATCH 30/33] docs: Add Cloud banner (#1763) * add banner * update colors * Include link + 20p disc message * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix typo * Update docs/conf.py * Update docs/conf.py --------- Co-authored-by: Sven Balnojan <43072233+sbalnojan@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Edgar R. M --- docs/conf.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index 87df1b6b7..c97ea6a5a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -69,9 +69,12 @@ "source_branch": "main", "source_directory": "docs/", "sidebar_hide_name": True, + "announcement": 'Sign up for Public Beta today! Get a 20% discount on purchases before 27th of July!', # noqa: E501 # branding "light_css_variables": { "font-stack": "Hanken Grotesk,-apple-system,Helvetica,sans-serif", + "color-announcement-background": "#3A64FA", + "color-announcement-text": "#EEEBEE", "color-foreground-primary": "#080216", "color-background-primary": "#E9E5FB", "color-link": "#3A64FA", From fd807e6670aaaf79f1e188b9e011c7811bca3318 Mon Sep 17 00:00:00 2001 From: Pat Nadolny Date: Tue, 20 Jun 2023 17:26:34 -0400 Subject: [PATCH 31/33] fix: Sink schema comparison before adding metadata columns (#1778) * add failing test for get_sink * refactor test mocks to share across modules * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * reformat * deep copy test schema so it doesnt get manipulated * fix sink schema compare test --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- singer_sdk/sinks/core.py | 2 ++ singer_sdk/target_base.py | 2 +- tests/conftest.py | 52 ++++++++++++++++++++++++++++++ tests/core/test_target_base.py | 30 ++++++++++++++++++ tests/samples/test_target_csv.py | 54 ++------------------------------ 5 files changed, 87 insertions(+), 53 deletions(-) create mode 100644 tests/core/test_target_base.py diff --git a/singer_sdk/sinks/core.py b/singer_sdk/sinks/core.py index fbcbbb295..2510be03c 100644 --- a/singer_sdk/sinks/core.py +++ b/singer_sdk/sinks/core.py @@ -3,6 +3,7 @@ from __future__ import annotations import abc +import copy import datetime import json import time @@ -67,6 +68,7 @@ def __init__( "Initializing target sink for stream '%s'...", stream_name, ) + self.original_schema = copy.deepcopy(schema) self.schema = schema if self.include_sdc_metadata_properties: self._add_sdc_metadata_to_schema() diff --git a/singer_sdk/target_base.py b/singer_sdk/target_base.py index 2fcb28314..d8320394a 100644 --- a/singer_sdk/target_base.py +++ b/singer_sdk/target_base.py @@ -167,7 +167,7 @@ def get_sink( return self.add_sink(stream_name, schema, key_properties) if ( - existing_sink.schema != schema + existing_sink.original_schema != schema or existing_sink.key_properties != key_properties ): self.logger.info( diff --git a/tests/conftest.py b/tests/conftest.py index c2992328a..142e76fe1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -9,6 +9,10 @@ import pytest +from singer_sdk import typing as th +from singer_sdk.sinks import BatchSink +from singer_sdk.target_base import Target + if t.TYPE_CHECKING: from _pytest.config import Config @@ -54,3 +58,51 @@ def outdir() -> t.Generator[str, None, None]: def snapshot_dir() -> pathlib.Path: """Return the path to the snapshot directory.""" return pathlib.Path("tests/snapshots/") + + +class BatchSinkMock(BatchSink): + """A mock Sink class.""" + + name = "batch-sink-mock" + + def __init__( + self, + target: TargetMock, + stream_name: str, + schema: dict, + key_properties: list[str] | None, + ): + """Create the Mock batch-based sink.""" + super().__init__(target, stream_name, schema, key_properties) + self.target = target + + def process_record(self, record: dict, context: dict) -> None: + """Tracks the count of processed records.""" + self.target.num_records_processed += 1 + super().process_record(record, context) + + def process_batch(self, context: dict) -> None: + """Write to mock trackers.""" + self.target.records_written.extend(context["records"]) + self.target.num_batches_processed += 1 + + +class TargetMock(Target): + """A mock Target class.""" + + name = "target-mock" + config_jsonschema = th.PropertiesList().to_dict() + default_sink_class = BatchSinkMock + + def __init__(self, *args, **kwargs): + """Create the Mock target sync.""" + super().__init__(*args, **kwargs) + self.state_messages_written: list[dict] = [] + self.records_written: list[dict] = [] + self.num_records_processed: int = 0 + self.num_batches_processed: int = 0 + + def _write_state_message(self, state: dict): + """Emit the stream's latest state.""" + super()._write_state_message(state) + self.state_messages_written.append(state) diff --git a/tests/core/test_target_base.py b/tests/core/test_target_base.py new file mode 100644 index 000000000..778fab722 --- /dev/null +++ b/tests/core/test_target_base.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +import copy + +from tests.conftest import BatchSinkMock, TargetMock + + +def test_get_sink(): + input_schema_1 = { + "properties": { + "id": { + "type": ["string", "null"], + }, + "col_ts": { + "format": "date-time", + "type": ["string", "null"], + }, + }, + } + input_schema_2 = copy.deepcopy(input_schema_1) + key_properties = [] + target = TargetMock(config={"add_record_metadata": True}) + sink = BatchSinkMock(target, "foo", input_schema_1, key_properties) + target._sinks_active["foo"] = sink + sink_returned = target.get_sink( + "foo", + schema=input_schema_2, + key_properties=key_properties, + ) + assert sink_returned == sink diff --git a/tests/samples/test_target_csv.py b/tests/samples/test_target_csv.py index 54f50fc38..715edbb65 100644 --- a/tests/samples/test_target_csv.py +++ b/tests/samples/test_target_csv.py @@ -14,9 +14,6 @@ from samples.sample_mapper.mapper import StreamTransform from samples.sample_tap_countries.countries_tap import SampleTapCountries from samples.sample_target_csv.csv_target import SampleTargetCSV -from singer_sdk import typing as th -from singer_sdk.sinks import BatchSink -from singer_sdk.target_base import Target from singer_sdk.testing import ( get_target_test_class, sync_end_to_end, @@ -24,6 +21,7 @@ tap_to_target_sync_test, target_sync_test, ) +from tests.conftest import TargetMock TEST_OUTPUT_DIR = Path(f".output/test_{uuid.uuid4()}/") SAMPLE_CONFIG = {"target_folder": f"{TEST_OUTPUT_DIR}/"} @@ -55,54 +53,6 @@ def resource(self, test_output_dir): } -class BatchSinkMock(BatchSink): - """A mock Sink class.""" - - name = "batch-sink-mock" - - def __init__( - self, - target: TargetMock, - stream_name: str, - schema: dict, - key_properties: list[str] | None, - ): - """Create the Mock batch-based sink.""" - super().__init__(target, stream_name, schema, key_properties) - self.target = target - - def process_record(self, record: dict, context: dict) -> None: - """Tracks the count of processed records.""" - self.target.num_records_processed += 1 - super().process_record(record, context) - - def process_batch(self, context: dict) -> None: - """Write to mock trackers.""" - self.target.records_written.extend(context["records"]) - self.target.num_batches_processed += 1 - - -class TargetMock(Target): - """A mock Target class.""" - - name = "target-mock" - config_jsonschema = th.PropertiesList().to_dict() - default_sink_class = BatchSinkMock - - def __init__(self): - """Create the Mock target sync.""" - super().__init__(config={}) - self.state_messages_written: list[dict] = [] - self.records_written: list[dict] = [] - self.num_records_processed: int = 0 - self.num_batches_processed: int = 0 - - def _write_state_message(self, state: dict): - """Emit the stream's latest state.""" - super()._write_state_message(state) - self.state_messages_written.append(state) - - def test_countries_to_csv(csv_config: dict): tap = SampleTapCountries(config=SAMPLE_TAP_CONFIG, state=None) target = SampleTargetCSV(config=csv_config) @@ -133,7 +83,7 @@ def test_target_batching(): countries_record_count = 257 with freeze_time(mocked_starttime): - target = TargetMock() + target = TargetMock(config={}) target.max_parallelism = 1 # Limit unit test to 1 process assert target.num_records_processed == 0 assert len(target.records_written) == 0 From d27f8addbb0d135a7860f7ca89f93e1589d622c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Jun 2023 13:32:02 +0000 Subject: [PATCH 32/33] chore(deps-dev): Bump mypy from 1.3.0 to 1.4.0 (#1780) --- poetry.lock | 54 ++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/poetry.lock b/poetry.lock index 363130529..f7b47cb6e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1198,37 +1198,37 @@ files = [ [[package]] name = "mypy" -version = "1.3.0" +version = "1.4.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.7" files = [ - {file = "mypy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eb485cea53f4f5284e5baf92902cd0088b24984f4209e25981cc359d64448d"}, - {file = "mypy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c99c3ecf223cf2952638da9cd82793d8f3c0c5fa8b6ae2b2d9ed1e1ff51ba85"}, - {file = "mypy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:550a8b3a19bb6589679a7c3c31f64312e7ff482a816c96e0cecec9ad3a7564dd"}, - {file = "mypy-1.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cbc07246253b9e3d7d74c9ff948cd0fd7a71afcc2b77c7f0a59c26e9395cb152"}, - {file = "mypy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:a22435632710a4fcf8acf86cbd0d69f68ac389a3892cb23fbad176d1cddaf228"}, - {file = "mypy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6e33bb8b2613614a33dff70565f4c803f889ebd2f859466e42b46e1df76018dd"}, - {file = "mypy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d23370d2a6b7a71dc65d1266f9a34e4cde9e8e21511322415db4b26f46f6b8c"}, - {file = "mypy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:658fe7b674769a0770d4b26cb4d6f005e88a442fe82446f020be8e5f5efb2fae"}, - {file = "mypy-1.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d29e324cdda61daaec2336c42512e59c7c375340bd202efa1fe0f7b8f8ca"}, - {file = "mypy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:d0b6c62206e04061e27009481cb0ec966f7d6172b5b936f3ead3d74f29fe3dcf"}, - {file = "mypy-1.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:76ec771e2342f1b558c36d49900dfe81d140361dd0d2df6cd71b3db1be155409"}, - {file = "mypy-1.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebc95f8386314272bbc817026f8ce8f4f0d2ef7ae44f947c4664efac9adec929"}, - {file = "mypy-1.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:faff86aa10c1aa4a10e1a301de160f3d8fc8703b88c7e98de46b531ff1276a9a"}, - {file = "mypy-1.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:8c5979d0deb27e0f4479bee18ea0f83732a893e81b78e62e2dda3e7e518c92ee"}, - {file = "mypy-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c5d2cc54175bab47011b09688b418db71403aefad07cbcd62d44010543fc143f"}, - {file = "mypy-1.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:87df44954c31d86df96c8bd6e80dfcd773473e877ac6176a8e29898bfb3501cb"}, - {file = "mypy-1.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:473117e310febe632ddf10e745a355714e771ffe534f06db40702775056614c4"}, - {file = "mypy-1.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:74bc9b6e0e79808bf8678d7678b2ae3736ea72d56eede3820bd3849823e7f305"}, - {file = "mypy-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:44797d031a41516fcf5cbfa652265bb994e53e51994c1bd649ffcd0c3a7eccbf"}, - {file = "mypy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ddae0f39ca146972ff6bb4399f3b2943884a774b8771ea0a8f50e971f5ea5ba8"}, - {file = "mypy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c4c42c60a8103ead4c1c060ac3cdd3ff01e18fddce6f1016e08939647a0e703"}, - {file = "mypy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e86c2c6852f62f8f2b24cb7a613ebe8e0c7dc1402c61d36a609174f63e0ff017"}, - {file = "mypy-1.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f9dca1e257d4cc129517779226753dbefb4f2266c4eaad610fc15c6a7e14283e"}, - {file = "mypy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:95d8d31a7713510685b05fbb18d6ac287a56c8f6554d88c19e73f724a445448a"}, - {file = "mypy-1.3.0-py3-none-any.whl", hash = "sha256:a8763e72d5d9574d45ce5881962bc8e9046bf7b375b0abf031f3e6811732a897"}, - {file = "mypy-1.3.0.tar.gz", hash = "sha256:e1f4d16e296f5135624b34e8fb741eb0eadedca90862405b1f1fde2040b9bd11"}, + {file = "mypy-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3af348e0925a59213244f28c7c0c3a2c2088b4ba2fe9d6c8d4fbb0aba0b7d05"}, + {file = "mypy-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0b2e0da7ff9dd8d2066d093d35a169305fc4e38db378281fce096768a3dbdbf"}, + {file = "mypy-1.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210fe0f39ec5be45dd9d0de253cb79245f0a6f27631d62e0c9c7988be7152965"}, + {file = "mypy-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f7a5971490fd4a5a436e143105a1f78fa8b3fe95b30fff2a77542b4f3227a01f"}, + {file = "mypy-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:50f65f0e9985f1e50040e603baebab83efed9eb37e15a22a4246fa7cd660f981"}, + {file = "mypy-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b1b5c875fcf3e7217a3de7f708166f641ca154b589664c44a6fd6d9f17d9e7e"}, + {file = "mypy-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b4c734d947e761c7ceb1f09a98359dd5666460acbc39f7d0a6b6beec373c5840"}, + {file = "mypy-1.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5984a8d13d35624e3b235a793c814433d810acba9eeefe665cdfed3d08bc3af"}, + {file = "mypy-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0f98973e39e4a98709546a9afd82e1ffcc50c6ec9ce6f7870f33ebbf0bd4f26d"}, + {file = "mypy-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:19d42b08c7532d736a7e0fb29525855e355fa51fd6aef4f9bbc80749ff64b1a2"}, + {file = "mypy-1.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6ba9a69172abaa73910643744d3848877d6aac4a20c41742027dcfd8d78f05d9"}, + {file = "mypy-1.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a34eed094c16cad0f6b0d889811592c7a9b7acf10d10a7356349e325d8704b4f"}, + {file = "mypy-1.4.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:53c2a1fed81e05ded10a4557fe12bae05b9ecf9153f162c662a71d924d504135"}, + {file = "mypy-1.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bba57b4d2328740749f676807fcf3036e9de723530781405cc5a5e41fc6e20de"}, + {file = "mypy-1.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:653863c75f0dbb687d92eb0d4bd9fe7047d096987ecac93bb7b1bc336de48ebd"}, + {file = "mypy-1.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7461469e163f87a087a5e7aa224102a30f037c11a096a0ceeb721cb0dce274c8"}, + {file = "mypy-1.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cf0ca95e4b8adeaf07815a78b4096b65adf64ea7871b39a2116c19497fcd0dd"}, + {file = "mypy-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:94a81b9354545123feb1a99b960faeff9e1fa204fce47e0042335b473d71530d"}, + {file = "mypy-1.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:67242d5b28ed0fa88edd8f880aed24da481929467fdbca6487167cb5e3fd31ff"}, + {file = "mypy-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3f2b353eebef669529d9bd5ae3566905a685ae98b3af3aad7476d0d519714758"}, + {file = "mypy-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:62bf18d97c6b089f77f0067b4e321db089d8520cdeefc6ae3ec0f873621c22e5"}, + {file = "mypy-1.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca33ab70a4aaa75bb01086a0b04f0ba8441e51e06fc57e28585176b08cad533b"}, + {file = "mypy-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5a0ee54c2cb0f957f8a6f41794d68f1a7e32b9968675ade5846f538504856d42"}, + {file = "mypy-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:6c34d43e3d54ad05024576aef28081d9d0580f6fa7f131255f54020eb12f5352"}, + {file = "mypy-1.4.0-py3-none-any.whl", hash = "sha256:f051ca656be0c179c735a4c3193f307d34c92fdc4908d44fd4516fbe8b10567d"}, + {file = "mypy-1.4.0.tar.gz", hash = "sha256:de1e7e68148a213036276d1f5303b3836ad9a774188961eb2684eddff593b042"}, ] [package.dependencies] From c6a893372d036a99da81ee9131b8b6e17f50e670 Mon Sep 17 00:00:00 2001 From: mjsqu Date: Thu, 22 Jun 2023 07:48:08 +1200 Subject: [PATCH 33/33] docs: Fix invalid JSON in Stream Maps page and add `meltano.yml` tabs (#1756) * Enable sphinx tabs * Add meltano.yml versions for all stream configs - Also removed trailing commas in list/dict objects to make the JSON syntactically valid - Removed all comments from JSON and added to meltano.yml tab * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Set meltano.yml as first tab * Set sphinx-inline-tabs to optional Co-authored-by: Edgar R. M. * Set null to __NULL__ for all undeclared/excluded map properties Co-authored-by: Edgar R. M. * `poetry lock` --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ken Payne Co-authored-by: Edgar R. M --- docs/conf.py | 1 + docs/stream_maps.md | 195 +++++++++++++++++++++++++++++++++++-------- poetry.lock | 198 ++++++++++++++++++++++++-------------------- pyproject.toml | 4 +- 4 files changed, 271 insertions(+), 127 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index c97ea6a5a..7b1f427bc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -42,6 +42,7 @@ "sphinx_copybutton", "myst_parser", "sphinx_reredirects", + "sphinx_inline_tabs", ] # Add any paths that contain templates here, relative to this directory. diff --git a/docs/stream_maps.md b/docs/stream_maps.md index 355426fba..e4119d640 100644 --- a/docs/stream_maps.md +++ b/docs/stream_maps.md @@ -107,23 +107,41 @@ The `stream_maps` config expects a mapping of stream names to a structured trans Here is a sample `stream_maps` transformation which removes all references to `email` and adds `email_domain` and `email_hash` as new properties: -`config.json`: +`meltano.yml` or `config.json`: + +````{tab} meltano.yml +```yaml +stream_maps: + # Apply these transforms to the stream called 'customers' + customers: + # drop the PII field from RECORD and SCHEMA messages + email: __NULL__ + # capture just the email domain + email_domain: owner_email.split('@')[-1] + # for uniqueness checks + email_hash: md5(config['hash_seed'] + owner_email) +stream_map_config: + # hash outputs are not able to be replicated without the original seed: + hash_seed: 01AWZh7A6DzGm6iJZZ2T +``` +```` -```js +````{tab} JSON +```json { "stream_maps": { - "customers": { // Apply these transforms to the stream called 'customers' - "email": null, // drop the PII field from RECORD and SCHEMA messages - "email_domain": "owner_email.split('@')[-1]", // capture just the email domain - "email_hash": "md5(config['hash_seed'] + owner_email)", // for uniqueness checks + "customers": { + "email": null, + "email_domain": "owner_email.split('@')[-1]", + "email_hash": "md5(config['hash_seed'] + owner_email)" } }, "stream_map_config": { - // hash outputs are not able to be replicated without the original seed: "hash_seed": "01AWZh7A6DzGm6iJZZ2T" } } ``` +```` If map expressions should have access to special config, such as in the one-way hash algorithm above, define those config arguments within the optional @@ -197,26 +215,47 @@ The following logic is applied in determining the SCHEMA of the transformed stre To remove a stream, declare the stream within `stream_maps` config and assign it the value `null`. For example: -```js +````{tab} meltano.yml +```yaml +stream_maps: + # don't sync the stream called 'addresses' + addresses: __NULL__ +``` +```` + +````{tab} JSON +```json { "stream_maps": { - "addresses": null // don't sync the stream called 'addresses' - }, + "addresses": null + } } ``` +```` To remove a property, declare the property within the designated stream's map entry and assign it the value `null`. For example: -```js +````{tab} meltano.yml +```yaml +stream_maps: + customers: + # don't sync the 'email' stream property + email: __NULL__ +``` +```` + +````{tab} JSON +```json { "stream_maps": { "customers": { - "email": null, // don't sync the 'email' stream property + "email": null } - }, + } } ``` +```` ### Remove all undeclared streams or properties @@ -230,43 +269,80 @@ below. To remove all streams except the `customers` stream: -```js +````{tab} meltano.yml +```yaml +stream_maps: + customers: {} + __else__: __NULL__ +``` +```` + +````{tab} JSON +```json { "stream_maps": { "customers": {}, "__else__": null - }, + } } ``` +```` To remove all fields from the `customers` stream except `customer_id`: -```js +````{tab} meltano.yml +```yaml +stream_maps: + customers: + customer_id: customer_id + __else__: __NULL__ +``` +```` + +````{tab} JSON +```json { "stream_maps": { "customers": { "customer_id": "customer_id", "__else__": null - }, - }, + } + } } ``` +```` ### Unset or modify the stream's primary key behavior To override the stream's default primary key properties, add the `__key_properties__` operation within the stream map definition. -```js +````{tab} meltano.yml +```yaml +stream_maps: + customers: + # Remove the original Customer ID column + customer_id: __NULL__ + # Add a new (and still unique) ID column + customer_id_hashed: md5(customer_id) + # Updated key to reflect the new name + __key_properties__: + - customer_id_hashed +``` +```` + +````{tab} JSON +```json { "stream_maps": { "customers": { - "customer_id": null, // Remove the original Customer ID column - "customer_id_hashed": "md5(customer_id)", // Add a new (and still unique) ID column - "__key_properties__": ["customer_id_hashed"] // Updated key to reflect the new name - }, - }, + "customer_id": null, + "customer_id_hashed": "md5(customer_id)", + "__key_properties__": ["customer_id_hashed"] + } + } } ``` +```` Notes: @@ -278,6 +354,15 @@ Notes: Some applications, such as multi-tenant, may benefit from adding a property with a hardcoded string literal value. These values need to be wrapped in double quotes to differentiate them from property names: +````{tab} meltano.yml +```yaml +stream_maps: + customers: + a_new_field: '\"client-123\"' +``` +```` + +````{tab} JSON ```json { "stream_maps": { @@ -287,6 +372,7 @@ These values need to be wrapped in double quotes to differentiate them from prop } } ``` +```` #### Q: What is the difference between `primary_keys` and `key_properties`? @@ -308,15 +394,25 @@ To alias a stream, simply add the operation `"__alias__": "new_name"` to the str definition. For example, to alias the `customers` stream as `customer_v2`, use the following: -```js +````{tab} meltano.yml +```yaml +stream_maps: + customers: + __alias__: customers_v2 +``` +```` + +````{tab} JSON +```json { "stream_maps": { "customers": { "__alias__": "customers_v2" - }, - }, + } + } } ``` +```` ## Duplicating or splitting a stream using `__source__` @@ -324,26 +420,43 @@ To create a new stream as a copy of the original, specify the operation `"__source__": "stream_name"`. For example, you can create a copy of the `customers` stream which only contains PII properties using the following: -```js +````{tab} meltano.yml +```yaml +stream_maps: + customers: + # Exclude these since we're capturing them in the pii stream + email: __NULL__ + full_name: __NULL__ + customers_pii: + __source__: customers + # include just the PII and the customer_id + customer_id: customer_id + email: email + full_name: full_name + # exclude anything not declared + __else__: __NULL__ +``` +```` + +````{tab} JSON +```json { "stream_maps": { "customers": { - // exclude these since we're capturing them in the pii stream "email": null, "full_name": null }, "customers_pii": { "__source__": "customers", - // include just the PII and the customer_id "customer_id": "customer_id", "email": "email", "full_name": "full_name", - // exclude anything not declared - "__else__": null, - }, - }, + "__else__": null + } + } } ``` +```` ## Filtering out records from a stream using `__filter__` operation @@ -352,15 +465,25 @@ The `__filter__` operation accept a string expression which must evaluate to `tr For example, to only include customers with emails from the `example.com` company domain: -```js +````{tab} meltano.yml +```yaml +stream_maps: + customers: + __filter__: email.endswith('@example.com') +``` +```` + +````{tab} JSON +```json { "stream_maps": { "customers": { "__filter__": "email.endswith('@example.com')" } - }, + } } ``` +```` ### Understanding Filters' Affects on Parent-Child Streams diff --git a/poetry.lock b/poetry.lock index f7b47cb6e..15aff2324 100644 --- a/poetry.lock +++ b/poetry.lock @@ -184,17 +184,17 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "boto3" -version = "1.26.129" +version = "1.26.157" description = "The AWS SDK for Python" optional = true python-versions = ">= 3.7" files = [ - {file = "boto3-1.26.129-py3-none-any.whl", hash = "sha256:1dab3fcbeada61a3b5a42ea25a89143511a5b22626775c685e31e313f327cf3c"}, - {file = "boto3-1.26.129.tar.gz", hash = "sha256:0686a62f424c4f3375a706555b765d1e24d03d70e7d317ffcb2d411b39aa8139"}, + {file = "boto3-1.26.157-py3-none-any.whl", hash = "sha256:718b236aafc3f106d17cd5c4f513fc2f40bfa995c0cb730ecc893e9c808c0385"}, + {file = "boto3-1.26.157.tar.gz", hash = "sha256:7a8117dfe9ba1f203d73b3df32a4ebdb895813189635f126fa256e1dea37ee8d"}, ] [package.dependencies] -botocore = ">=1.29.129,<1.30.0" +botocore = ">=1.29.157,<1.30.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.6.0,<0.7.0" @@ -203,13 +203,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.29.129" +version = "1.29.157" description = "Low-level, data-driven core of boto 3." optional = true python-versions = ">= 3.7" files = [ - {file = "botocore-1.29.129-py3-none-any.whl", hash = "sha256:f44460236324727615c518c229690c3cc3ea3162a55a2ac242ba771e8fa41553"}, - {file = "botocore-1.29.129.tar.gz", hash = "sha256:80370e835ccf12e0429d4c6cc0e9d03cf47b72c41ec5916b01fb9544765f314d"}, + {file = "botocore-1.29.157-py3-none-any.whl", hash = "sha256:ccbf948c040d68b6a22570e73dd63cb3b07ce33f4032e9b1d502d2fae55c3b80"}, + {file = "botocore-1.29.157.tar.gz", hash = "sha256:af2a7b6417bf3bbf00ab22aa61a2d7d839a8a8a62e7975c18c80c55c88dc7fcf"}, ] [package.dependencies] @@ -430,13 +430,13 @@ files = [ [[package]] name = "commitizen" -version = "3.2.1" +version = "3.4.0" description = "Python commitizen client tool" optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "commitizen-3.2.1-py3-none-any.whl", hash = "sha256:3723a5bf612e75d9cd1b0499ca2902e96d5fa8aaaada3c3b8b5888039edd26a0"}, - {file = "commitizen-3.2.1.tar.gz", hash = "sha256:2d62fd099e81b5126d1870ada6c7e96ebb561cc27357bd2ce6930c0f5c573c21"}, + {file = "commitizen-3.4.0-py3-none-any.whl", hash = "sha256:5c58052099a6512da66a893f09e98e1f0d94ed02720a4e8d5747d4d409d59cfb"}, + {file = "commitizen-3.4.0.tar.gz", hash = "sha256:ab17db8c4f7258d9cdcc620046aa63d2139756ef78b2174cfa9f9c5e383eaf27"}, ] [package.dependencies] @@ -470,7 +470,7 @@ PyGithub = "^1.57" type = "git" url = "https://github.com/meltano/commitizen-version-bump.git" reference = "main" -resolved_reference = "2ac24303b30441773d95357d5c2801275211ce5f" +resolved_reference = "e2e6d5d13d39eae1f37e3a275c0d3d3e38c18439" [[package]] name = "cookiecutter" @@ -621,13 +621,13 @@ files = [ [[package]] name = "decli" -version = "0.6.0" +version = "0.6.1" description = "Minimal, easy-to-use, declarative cli tool" optional = false python-versions = ">=3.7" files = [ - {file = "decli-0.6.0-py3-none-any.whl", hash = "sha256:d5ed1d509f5a6cf765a4d7350f7ffb0be0c1770840cbd38b05fb0aab642645e8"}, - {file = "decli-0.6.0.tar.gz", hash = "sha256:2915a55525ef2b1a0ce88b8ccba62ac22df5b6ff3ed2094448e0f951f08e7ba5"}, + {file = "decli-0.6.1-py3-none-any.whl", hash = "sha256:7815ac58617764e1a200d7cadac6315fcaacc24d727d182f9878dd6378ccf869"}, + {file = "decli-0.6.1.tar.gz", hash = "sha256:ed88ccb947701e8e5509b7945fda56e150e2ac74a69f25d47ac85ef30ab0c0f0"}, ] [[package]] @@ -643,20 +643,20 @@ files = [ [[package]] name = "deprecated" -version = "1.2.13" +version = "1.2.14" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ - {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, - {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, + {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, + {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, ] [package.dependencies] wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] [[package]] name = "docutils" @@ -1088,61 +1088,61 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" -version = "2.1.2" +version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, - {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, - {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, - {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, - {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, - {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, - {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, ] [[package]] @@ -1427,21 +1427,21 @@ files = [ [[package]] name = "platformdirs" -version = "3.5.0" +version = "3.6.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.5.0-py3-none-any.whl", hash = "sha256:47692bc24c1958e8b0f13dd727307cff1db103fca36399f457da8e05f222fdc4"}, - {file = "platformdirs-3.5.0.tar.gz", hash = "sha256:7954a68d0ba23558d753f73437c55f89027cf8f5108c19844d4b82e5af396335"}, + {file = "platformdirs-3.6.0-py3-none-any.whl", hash = "sha256:ffa199e3fbab8365778c4a10e1fbf1b9cd50707de826eb304b50e57ec0cc8d38"}, + {file = "platformdirs-3.6.0.tar.gz", hash = "sha256:57e28820ca8094678b807ff529196506d7a21e17156cb1cddb3e74cebce54640"}, ] [package.dependencies] -typing-extensions = {version = ">=4.5", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=4.6.3", markers = "python_version < \"3.8\""} [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" @@ -1576,13 +1576,13 @@ files = [ [[package]] name = "pygithub" -version = "1.58.1" +version = "1.58.2" description = "Use the full Github API v3" optional = false python-versions = ">=3.7" files = [ - {file = "PyGithub-1.58.1-py3-none-any.whl", hash = "sha256:4e7fe9c3ec30d5fde5b4fbb97f18821c9dbf372bf6df337fe66f6689a65e0a83"}, - {file = "PyGithub-1.58.1.tar.gz", hash = "sha256:7d528b4ad92bc13122129fafd444ce3d04c47d2d801f6446b6e6ee2d410235b3"}, + {file = "PyGithub-1.58.2-py3-none-any.whl", hash = "sha256:f435884af617c6debaa76cbc355372d1027445a56fbc39972a3b9ed4968badc8"}, + {file = "PyGithub-1.58.2.tar.gz", hash = "sha256:1e6b1b7afe31f75151fb81f7ab6b984a7188a852bdb123dbb9ae90023c3ce60f"}, ] [package.dependencies] @@ -1931,18 +1931,18 @@ crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] [[package]] name = "setuptools" -version = "67.7.2" +version = "68.0.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"}, - {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"}, + {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, + {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -2161,6 +2161,24 @@ sphinx = ">=1.8" code-style = ["pre-commit (==2.12.1)"] rtd = ["ipython", "myst-nb", "sphinx", "sphinx-book-theme", "sphinx-examples"] +[[package]] +name = "sphinx-inline-tabs" +version = "2023.4.21" +description = "Add inline tabbed content to your Sphinx documentation." +optional = true +python-versions = ">=3.8" +files = [ + {file = "sphinx_inline_tabs-2023.4.21-py3-none-any.whl", hash = "sha256:06809ac613f7c48ddd6e2fa588413e3fe92cff2397b56e2ccf0b0218f9ef6a78"}, + {file = "sphinx_inline_tabs-2023.4.21.tar.gz", hash = "sha256:5df2f13f602c158f3f5f6c509e008aeada199a8c76d97ba3aa2822206683bebc"}, +] + +[package.dependencies] +sphinx = ">=3" + +[package.extras] +doc = ["furo", "myst-parser"] +test = ["pytest", "pytest-cov", "pytest-xdist"] + [[package]] name = "sphinx-reredirects" version = "0.1.2" @@ -2524,13 +2542,13 @@ files = [ [[package]] name = "types-urllib3" -version = "1.26.25.12" +version = "1.26.25.13" description = "Typing stubs for urllib3" optional = false python-versions = "*" files = [ - {file = "types-urllib3-1.26.25.12.tar.gz", hash = "sha256:a1557355ce8d350a555d142589f3001903757d2d36c18a66f588d9659bbc917d"}, - {file = "types_urllib3-1.26.25.12-py3-none-any.whl", hash = "sha256:3ba3d3a8ee46e0d5512c6bd0594da4f10b2584b47a470f8422044a2ab462f1df"}, + {file = "types-urllib3-1.26.25.13.tar.gz", hash = "sha256:3300538c9dc11dad32eae4827ac313f5d986b8b21494801f1bf97a1ac6c03ae5"}, + {file = "types_urllib3-1.26.25.13-py3-none-any.whl", hash = "sha256:5dbd1d2bef14efee43f5318b5d36d805a489f6600252bb53626d4bfafd95e27c"}, ] [[package]] @@ -2546,13 +2564,13 @@ files = [ [[package]] name = "urllib3" -version = "1.26.15" +version = "1.26.16" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ - {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, - {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, + {file = "urllib3-1.26.16-py2.py3-none-any.whl", hash = "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f"}, + {file = "urllib3-1.26.16.tar.gz", hash = "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"}, ] [package.extras] @@ -2698,11 +2716,11 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [extras] -docs = ["furo", "myst-parser", "sphinx", "sphinx-autobuild", "sphinx-copybutton", "sphinx-reredirects"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-reredirects"] s3 = ["fs-s3fs"] testing = ["pytest", "pytest-durations"] [metadata] lock-version = "2.0" python-versions = "<3.12,>=3.7.1" -content-hash = "e4ace691c7a3c5651576ee45fa03de04fb21abc1eb66f0ab99cf72015ab5dd2d" +content-hash = "53c3e577e500c322fffa5a7f3e5fcebe34a2657894d35a9d5768b951320448d0" diff --git a/pyproject.toml b/pyproject.toml index 3c0384d3c..e05d685d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,6 +70,7 @@ sphinx-copybutton = {version = ">=0.3.1,<0.6.0", optional = true} myst-parser = {version = ">=0.17.2,<1.1.0", optional = true} sphinx-autobuild = {version = "^2021.3.14", optional = true} sphinx-reredirects = {version = "^0.1.1", optional = true} +sphinx-inline-tabs = {version = ">=2023.4.21", optional = true, markers = "python_version >= \"3.8\""} # File storage dependencies installed as optional 'filesystem' extras fs-s3fs = {version = "^1.1.1", optional = true} @@ -85,7 +86,8 @@ docs = [ "sphinx-copybutton", "myst-parser", "sphinx-autobuild", - "sphinx_reredirects", + "sphinx-reredirects", + "sphinx-inline-tabs", ] s3 = ["fs-s3fs"] testing = [