diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4f2ec7747b43..f1ec6bb53f1c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,26 +25,16 @@ repos: rev: 22.12.0 hooks: - id: black - - repo: https://github.com/pycqa/flake8 - rev: 6.0.0 + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.0.189 hooks: - - id: flake8 - exclude: (^ibis/tests/sql/snapshots/|_py310\.py$) + - id: ruff + # makes sure to exclude a file even if it's passed in explicitly + args: ["--force-exclude"] - repo: https://github.com/pycqa/docformatter rev: v1.5.1 hooks: - id: docformatter - - repo: https://github.com/MarcoGorelli/absolufy-imports - rev: v0.3.1 - hooks: - - id: absolufy-imports - - repo: https://github.com/asottile/pyupgrade - rev: v3.3.1 - hooks: - - id: pyupgrade - entry: pyupgrade --py38-plus --keep-runtime-typing - types: - - python - repo: local hooks: - id: prettier @@ -111,6 +101,5 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: - - id: debug-statements - id: check-executables-have-shebangs - id: check-shebang-scripts-are-executable diff --git a/ci/make_geography_db.py b/ci/make_geography_db.py index 6677933a3159..85c72ee71edf 100755 --- a/ci/make_geography_db.py +++ b/ci/make_geography_db.py @@ -110,7 +110,7 @@ def main() -> None: db_path = Path(args.output_directory).joinpath("geography.db") con = sa.create_engine(f"sqlite:///{db_path}") make_geography_db(input_data, con) - print(db_path) + print(db_path) # noqa: T201 if __name__ == "__main__": diff --git a/ibis/__init__.py b/ibis/__init__.py index d2c03000a49e..49b106f1105c 100644 --- a/ibis/__init__.py +++ b/ibis/__init__.py @@ -7,7 +7,7 @@ from ibis.config import options from ibis.expr import api from ibis.expr import types as ir -from ibis.expr.api import * # noqa: F401,F403 +from ibis.expr.api import * # noqa: F403 __all__ = ['api', 'ir', 'util', 'BaseBackend', 'IbisError', 'options'] __all__ += api.__all__ diff --git a/ibis/backends/base/__init__.py b/ibis/backends/base/__init__.py index 1ab8b97553ee..3c864097c579 100644 --- a/ibis/backends/base/__init__.py +++ b/ibis/backends/base/__init__.py @@ -178,7 +178,7 @@ def __init__(self, backend: BaseBackend): def __getitem__(self, name) -> ir.Table: try: return self._backend.table(name) - except Exception as exc: + except Exception as exc: # noqa: BLE001 raise KeyError(name) from exc def __getattr__(self, name) -> ir.Table: @@ -186,7 +186,7 @@ def __getattr__(self, name) -> ir.Table: raise AttributeError(name) try: return self._backend.table(name) - except Exception as exc: + except Exception as exc: # noqa: BLE001 raise AttributeError(name) from exc def __iter__(self) -> Iterator[str]: @@ -217,7 +217,7 @@ def _import_pyarrow(): import pyarrow except ImportError: raise ModuleNotFoundError( - "Exporting to arrow formats requires `pyarrow` but it is not installed" # noqa: ignore + "Exporting to arrow formats requires `pyarrow` but it is not installed" ) else: return pyarrow diff --git a/ibis/backends/base/sql/__init__.py b/ibis/backends/base/sql/__init__.py index 1d29e026c5d2..da8dec3d66a8 100644 --- a/ibis/backends/base/sql/__init__.py +++ b/ibis/backends/base/sql/__init__.py @@ -135,6 +135,7 @@ def raw_sql(self, query: str) -> Any: if cursor: return cursor cursor.release() + return None @contextlib.contextmanager def _safe_raw_sql(self, *args, **kwargs): diff --git a/ibis/backends/base/sql/compiler/query_builder.py b/ibis/backends/base/sql/compiler/query_builder.py index 0c2b1a29dc14..5f653dcc7aee 100644 --- a/ibis/backends/base/sql/compiler/query_builder.py +++ b/ibis/backends/base/sql/compiler/query_builder.py @@ -279,7 +279,7 @@ def compile(self): def format_subqueries(self): if not self.subqueries: - return + return None context = self.context diff --git a/ibis/backends/base/sql/ddl.py b/ibis/backends/base/sql/ddl.py index 6605865b4ead..139a4cdf0273 100644 --- a/ibis/backends/base/sql/ddl.py +++ b/ibis/backends/base/sql/ddl.py @@ -11,7 +11,7 @@ def _sanitize_format(format): if format is None: - return + return None format = format.upper() format = _format_aliases.get(format, format) if format not in ('PARQUET', 'AVRO', 'TEXTFILE'): diff --git a/ibis/backends/base/sql/registry/string.py b/ibis/backends/base/sql/registry/string.py index c3df9fae85e1..cfa88520b22a 100644 --- a/ibis/backends/base/sql/registry/string.py +++ b/ibis/backends/base/sql/registry/string.py @@ -36,6 +36,8 @@ def string_find(translator, op): return 'locate({}, {}, {}) - 1'.format( substr_formatted, arg_formatted, sval + 1 ) + else: + raise ValueError(f"invalid `start` value: {sval}") else: return f'locate({substr_formatted}, {arg_formatted}) - 1' diff --git a/ibis/backends/bigquery/tests/unit/udf/test_core.py b/ibis/backends/bigquery/tests/unit/udf/test_core.py index e99ae18b334b..29f7662d6057 100644 --- a/ibis/backends/bigquery/tests/unit/udf/test_core.py +++ b/ibis/backends/bigquery/tests/unit/udf/test_core.py @@ -64,7 +64,7 @@ def test_assign(snapshot): def f(): a = 1 a = 2 - print(a) + print(a) # noqa: T201 return 1 js = compile(f) diff --git a/ibis/backends/bigquery/udf/core.py b/ibis/backends/bigquery/udf/core.py index ec7c3d03cfc5..7fc77c4a6395 100644 --- a/ibis/backends/bigquery/udf/core.py +++ b/ibis/backends/bigquery/udf/core.py @@ -560,9 +560,9 @@ def range(n): some_stuff = [x + y for x, y in [[1, 4], [2, 5], [3, 6]] if 2 < x < 3] some_stuff1 = [range(x) for x in [1, 2, 3]] some_stuff2 = [x + y for x, y in [(1, 4), (2, 5), (3, 6)]] - print(some_stuff) - print(some_stuff1) - print(some_stuff2) + print(some_stuff) # noqa: T201 + print(some_stuff1) # noqa: T201 + print(some_stuff2) # noqa: T201 x = 1 y = 2 @@ -591,7 +591,7 @@ def range(n): w = 3 w = not False yyz = None - print(yyz) + print(yyz) # noqa: T201 foobar = x < y < z < w # x < y and y < z foobar = 1 baz = foobar // 3 @@ -604,4 +604,4 @@ def range(n): nnn = len(values) return [sum(values) - a + b * y**-x, z, foo.width, nnn] - print(my_func.js) + print(my_func.js) # noqa: T201 diff --git a/ibis/backends/clickhouse/__init__.py b/ibis/backends/clickhouse/__init__.py index f9d372074658..d530d4403f86 100644 --- a/ibis/backends/clickhouse/__init__.py +++ b/ibis/backends/clickhouse/__init__.py @@ -181,7 +181,7 @@ def do_connect( >>> client = ibis.clickhouse.connect(host=clickhouse_host, port=clickhouse_port) >>> client # doctest: +ELLIPSIS - """ # noqa: E501 + """ options = dict( host=host, port=port, diff --git a/ibis/backends/clickhouse/tests/test_client.py b/ibis/backends/clickhouse/tests/test_client.py index 7cdbdd0c75f7..8db6672c5190 100644 --- a/ibis/backends/clickhouse/tests/test_client.py +++ b/ibis/backends/clickhouse/tests/test_client.py @@ -176,7 +176,7 @@ def test_insert_with_more_columns(temporary_alltypes, df): ibis.schema(dict(a=dt.UInt8(nullable=False), b=dt.UInt16(nullable=False))), ), ( - "SELECT string_col, sum(double_col) as b FROM functional_alltypes GROUP BY string_col", # noqa: E501 + "SELECT string_col, sum(double_col) as b FROM functional_alltypes GROUP BY string_col", ibis.schema( dict( string_col=dt.String(nullable=True), diff --git a/ibis/backends/clickhouse/tests/test_operators.py b/ibis/backends/clickhouse/tests/test_operators.py index 279c991845c8..25645638288e 100644 --- a/ibis/backends/clickhouse/tests/test_operators.py +++ b/ibis/backends/clickhouse/tests/test_operators.py @@ -220,7 +220,7 @@ def test_simple_case(con, alltypes, translate): t.string_col.case().when('foo', 'bar').when('baz', 'qux').else_('default').end() ) - expected = """CASE string_col WHEN 'foo' THEN 'bar' WHEN 'baz' THEN 'qux' ELSE 'default' END""" # noqa: E501 + expected = """CASE string_col WHEN 'foo' THEN 'bar' WHEN 'baz' THEN 'qux' ELSE 'default' END""" assert translate(expr.op()) == expected assert len(con.execute(expr)) @@ -235,7 +235,7 @@ def test_search_case(con, alltypes, translate): .end() ) - expected = """CASE WHEN float_col > 0 THEN int_col * 2 WHEN float_col < 0 THEN int_col ELSE 0 END""" # noqa: E501 + expected = """CASE WHEN float_col > 0 THEN int_col * 2 WHEN float_col < 0 THEN int_col ELSE 0 END""" assert translate(expr.op()) == expected assert len(con.execute(expr)) diff --git a/ibis/backends/conftest.py b/ibis/backends/conftest.py index 4071c2f80d76..6ca42e3057bd 100644 --- a/ibis/backends/conftest.py +++ b/ibis/backends/conftest.py @@ -484,6 +484,7 @@ def _setup_backend( "windows prevents two connections to the same duckdb file " "even in the same process" ) + return None else: cls = _get_backend_conf(backend) return cls.load_data( diff --git a/ibis/backends/dask/execution/__init__.py b/ibis/backends/dask/execution/__init__.py index 5ce0b2fb68d0..39d0861c213c 100644 --- a/ibis/backends/dask/execution/__init__.py +++ b/ibis/backends/dask/execution/__init__.py @@ -1,14 +1,14 @@ -from ibis.backends.dask.execution.aggregations import * # noqa: F401,F403 -from ibis.backends.dask.execution.arrays import * # noqa: F401,F403 -from ibis.backends.dask.execution.decimal import * # noqa: F401,F403 -from ibis.backends.dask.execution.generic import * # noqa: F401,F403 -from ibis.backends.dask.execution.indexing import * # noqa: F401,F403 -from ibis.backends.dask.execution.join import * # noqa: F401,F403 -from ibis.backends.dask.execution.maps import * # noqa: F401,F403 -from ibis.backends.dask.execution.numeric import * # noqa: F401,F403 -from ibis.backends.dask.execution.reductions import * # noqa: F401,F403 -from ibis.backends.dask.execution.selection import * # noqa: F401,F403 -from ibis.backends.dask.execution.strings import * # noqa: F401,F403 -from ibis.backends.dask.execution.structs import * # noqa: F401,F403 -from ibis.backends.dask.execution.temporal import * # noqa: F401,F403 -from ibis.backends.dask.execution.window import * # noqa: F401,F403 +from ibis.backends.dask.execution.aggregations import * # noqa: F403 +from ibis.backends.dask.execution.arrays import * # noqa: F403 +from ibis.backends.dask.execution.decimal import * # noqa: F403 +from ibis.backends.dask.execution.generic import * # noqa: F403 +from ibis.backends.dask.execution.indexing import * # noqa: F403 +from ibis.backends.dask.execution.join import * # noqa: F403 +from ibis.backends.dask.execution.maps import * # noqa: F403 +from ibis.backends.dask.execution.numeric import * # noqa: F403 +from ibis.backends.dask.execution.reductions import * # noqa: F403 +from ibis.backends.dask.execution.selection import * # noqa: F403 +from ibis.backends.dask.execution.strings import * # noqa: F403 +from ibis.backends.dask.execution.structs import * # noqa: F403 +from ibis.backends.dask.execution.temporal import * # noqa: F403 +from ibis.backends.dask.execution.window import * # noqa: F403 diff --git a/ibis/backends/dask/execution/maps.py b/ibis/backends/dask/execution/maps.py index 8c183e679238..aaa2892b23e9 100644 --- a/ibis/backends/dask/execution/maps.py +++ b/ibis/backends/dask/execution/maps.py @@ -2,7 +2,7 @@ import dask.dataframe as dd import numpy as np -import pandas +import pandas as pd import ibis.expr.operations as ops from ibis.backends.dask.dispatch import execute_node @@ -33,8 +33,8 @@ # https://multiple-dispatch.readthedocs.io/en/latest/resolution.html#ambiguities # for more detail. PANDAS_REGISTERED_TYPES = [ - (ops.MapGet, Mapping, object, pandas.Series), - (ops.MapGet, Mapping, pandas.Series, object), + (ops.MapGet, Mapping, object, pd.Series), + (ops.MapGet, Mapping, pd.Series, object), ] for registered_type in PANDAS_REGISTERED_TYPES: del execute_node[registered_type] @@ -46,24 +46,15 @@ ((dd.Series, object, object), map_get_series_scalar_scalar), ((dd.Series, object, dd.Series), map_get_series_scalar_series), ((dd.Series, dd.Series, object), map_get_series_series_scalar), - ( - (dd.Series, dd.Series, dd.Series), - map_get_series_series_series, - ), + ((dd.Series, dd.Series, dd.Series), map_get_series_series_series), # This never occurs but we need to register it so multipledispatch # does not see below registrations as ambigious. See NOTE above. ( - (Mapping, (dd.Series, pandas.Series), (dd.Series, pandas.Series)), + (Mapping, (dd.Series, pd.Series), (dd.Series, pd.Series)), map_get_dict_series_series, ), - ( - (Mapping, object, (dd.Series, pandas.Series)), - map_get_dict_scalar_series, - ), - ( - (Mapping, (dd.Series, pandas.Series), object), - map_get_dict_series_scalar, - ), + ((Mapping, object, (dd.Series, pd.Series)), map_get_dict_scalar_series), + ((Mapping, (dd.Series, pd.Series), object), map_get_dict_series_scalar), ], ops.MapContains: [ ((Mapping, dd.Series), map_contains_dict_series), diff --git a/ibis/backends/dask/execution/selection.py b/ibis/backends/dask/execution/selection.py index e0a9c0c8c9bf..a205d036a1fa 100644 --- a/ibis/backends/dask/execution/selection.py +++ b/ibis/backends/dask/execution/selection.py @@ -7,7 +7,7 @@ from typing import TYPE_CHECKING import dask.dataframe as dd -import pandas +import pandas as pd from toolz import concatv import ibis.expr.analysis as an @@ -223,7 +223,7 @@ def execute_selection_dataframe( return result # create a sequence of columns that we need to drop - temporary_columns = pandas.Index(concatv(grouping_keys, ordering_keys)).difference( + temporary_columns = pd.Index(concatv(grouping_keys, ordering_keys)).difference( data.columns ) diff --git a/ibis/backends/dask/execution/strings.py b/ibis/backends/dask/execution/strings.py index f26b2d181330..3e9cfd4987a7 100644 --- a/ibis/backends/dask/execution/strings.py +++ b/ibis/backends/dask/execution/strings.py @@ -5,7 +5,7 @@ import dask.dataframe as dd import dask.dataframe.groupby as ddgb import numpy as np -import pandas +import pandas as pd import toolz from pandas import isnull @@ -254,7 +254,7 @@ def method(series, sep=sep): @execute_node.register(ops.StringAscii, dd.Series) def execute_string_ascii(op, data, **kwargs): - output_meta = pandas.Series([], dtype=np.dtype('int32'), name=data.name) + output_meta = pd.Series([], dtype=np.dtype('int32'), name=data.name) return data.map(ord, meta=output_meta) diff --git a/ibis/backends/dask/execution/util.py b/ibis/backends/dask/execution/util.py index 552c55521adb..34fb6dc0e563 100644 --- a/ibis/backends/dask/execution/util.py +++ b/ibis/backends/dask/execution/util.py @@ -186,7 +186,7 @@ def safe_concat(dfs: list[dd.Series | dd.DataFrame]) -> dd.DataFrame: path is aggregations where aggregations return different numbers of rows (see `test_aggregation_group_by` for a specific example). TODO - performance. - """ # noqa: E501 + """ if len(dfs) == 1: maybe_df = dfs[0] if isinstance(maybe_df, dd.Series): diff --git a/ibis/backends/dask/udf.py b/ibis/backends/dask/udf.py index 3504ca5f0176..dd35c20a12ce 100644 --- a/ibis/backends/dask/udf.py +++ b/ibis/backends/dask/udf.py @@ -5,7 +5,7 @@ import dask.dataframe.groupby as ddgb import dask.delayed import numpy as np -import pandas +import pandas as pd import ibis.expr.operations as ops import ibis.expr.types as ir @@ -78,7 +78,7 @@ def execute_udf_node(op, *args, cache=None, timecontext=None, **kwargs): df = dd.map_partitions(op.func, *args, meta=meta) else: name = args[0].name if len(args) == 1 else None - meta = pandas.Series([], name=name, dtype=op.return_type.to_dask()) + meta = pd.Series([], name=name, dtype=op.return_type.to_dask()) df = dd.map_partitions(op.func, *args, meta=meta) cache[(op, timecontext)] = df @@ -108,7 +108,7 @@ def execute_udaf_node_no_groupby(op, *args, aggcontext, **kwargs): # passing that (now) pd.Series to aggctx. This materialization # happens at `.compute()` time, making this "lazy" @dask.delayed - def lazy_agg(*series: pandas.Series): + def lazy_agg(*series: pd.Series): return aggcontext.agg(series[0], op.func, *series[1:]) lazy_result = lazy_agg(*args) @@ -193,19 +193,19 @@ def apply_wrapper(df, apply_func, col_names): return apply_func(*cols) if len(groupings) > 1: - meta_index = pandas.MultiIndex.from_arrays( + meta_index = pd.MultiIndex.from_arrays( [[0]] * len(groupings), names=groupings ) meta_value = [dd.utils.make_meta(out_type)] else: - meta_index = pandas.Index([], name=groupings[0]) + meta_index = pd.Index([], name=groupings[0]) meta_value = [] return grouped_df.apply( apply_wrapper, func, col_names, - meta=pandas.Series(meta_value, index=meta_index, dtype=out_type), + meta=pd.Series(meta_value, index=meta_index, dtype=out_type), ) @execute_node.register( @@ -254,7 +254,7 @@ def apply_wrapper(df, apply_func, col_names): else: # after application we will get a series with a multi-index of # groupings + index - meta_index = pandas.MultiIndex.from_arrays( + meta_index = pd.MultiIndex.from_arrays( [[0]] * (len(groupings) + 1), names=groupings + [parent_df.index.name], ) @@ -264,7 +264,7 @@ def apply_wrapper(df, apply_func, col_names): apply_wrapper, func, col_names, - meta=pandas.Series(meta_value, index=meta_index, dtype=out_type), + meta=pd.Series(meta_value, index=meta_index, dtype=out_type), ) return result diff --git a/ibis/backends/duckdb/registry.py b/ibis/backends/duckdb/registry.py index 7078fd6bbeb7..339c5be51115 100644 --- a/ibis/backends/duckdb/registry.py +++ b/ibis/backends/duckdb/registry.py @@ -59,13 +59,12 @@ def _timestamp_from_unix(t, op): arg, unit = op.args arg = t.translate(arg) - if unit in {"us", "ns"}: - raise ValueError(f"`{unit}` unit is not supported!") - if unit == "ms": return sa.func.epoch_ms(arg) elif unit == "s": return sa.func.to_timestamp(arg) + else: + raise ValueError(f"`{unit}` unit is not supported!") def _literal(_, op): @@ -218,7 +217,7 @@ def _struct_column(t, op): ), ops.ApproxMedian: reduction( # without inline text, duckdb fails with - # RuntimeError: INTERNAL Error: Invalid PhysicalType for GetTypeIdSize # noqa: E501 + # RuntimeError: INTERNAL Error: Invalid PhysicalType for GetTypeIdSize lambda arg: sa.func.approx_quantile(arg, sa.text(str(0.5))) ), ops.HLLCardinality: reduction(sa.func.approx_count_distinct), diff --git a/ibis/backends/duckdb/tests/conftest.py b/ibis/backends/duckdb/tests/conftest.py index 9382e59e0aca..c67acc2c5704 100644 --- a/ibis/backends/duckdb/tests/conftest.py +++ b/ibis/backends/duckdb/tests/conftest.py @@ -45,7 +45,7 @@ def _load_data( for table in TEST_TABLES: src = data_dir / f'{table}.csv' conn.execute( - f"COPY {table} FROM {str(src)!r} (DELIMITER ',', HEADER, SAMPLE_SIZE 1)" # noqa: E501 + f"COPY {table} FROM {str(src)!r} (DELIMITER ',', HEADER, SAMPLE_SIZE 1)" ) @staticmethod diff --git a/ibis/backends/impala/__init__.py b/ibis/backends/impala/__init__.py index 1d9f43479fee..f9046c573a15 100644 --- a/ibis/backends/impala/__init__.py +++ b/ibis/backends/impala/__init__.py @@ -39,7 +39,7 @@ from ibis.backends.impala.compat import HS2Error, ImpylaError from ibis.backends.impala.compiler import ImpalaCompiler from ibis.backends.impala.pandas_interop import DataFrameWriter -from ibis.backends.impala.udf import ( # noqa: F401 +from ibis.backends.impala.udf import ( aggregate_function, scalar_function, wrap_uda, @@ -51,6 +51,14 @@ import pandas as pd +__all__ = ( + "Backend", + "aggregate_function", + "scalar_function", + "wrap_uda", + "wrap_udf", +) + _HS2_TTypeId_to_dtype = { 'BOOLEAN': 'bool', 'TINYINT': 'int8', @@ -958,10 +966,10 @@ def drop_table_or_view(self, name, database=None, force=False): """Drop view or table.""" try: self.drop_table(name, database=database) - except Exception as e: + except Exception as e: # noqa: BLE001 try: self.drop_view(name, database=database) - except Exception: + except Exception: # noqa: BLE001 raise e def cache_table(self, table_name, database=None, pool='default'): diff --git a/ibis/backends/impala/client.py b/ibis/backends/impala/client.py index bbe1b77b0378..68f7174fdd67 100644 --- a/ibis/backends/impala/client.py +++ b/ibis/backends/impala/client.py @@ -1,5 +1,6 @@ from __future__ import annotations +import contextlib import time import traceback from typing import TYPE_CHECKING @@ -130,10 +131,8 @@ def __init__(self, cursor, impyla_con, database, options): self.options = options def __del__(self): - try: + with contextlib.suppress(Exception): self.close() - except Exception: - pass def close(self): try: diff --git a/ibis/backends/impala/metadata.py b/ibis/backends/impala/metadata.py index 97d93227ffe9..3312fe77a992 100644 --- a/ibis/backends/impala/metadata.py +++ b/ibis/backends/impala/metadata.py @@ -306,7 +306,7 @@ def __repr__(self): if self.partitions is not None: data['partition schema'] = self.partitions - pprint.pprint(data, stream=buf) + pprint.pprint(data, stream=buf) # noqa: T203 return buf.getvalue() diff --git a/ibis/backends/impala/udf.py b/ibis/backends/impala/udf.py index f4036a936ddc..3346a9ff69c0 100644 --- a/ibis/backends/impala/udf.py +++ b/ibis/backends/impala/udf.py @@ -301,6 +301,7 @@ def _parse_varchar(t): m = _VARCHAR_RE.match(t) if m: return 'string' + return None def _impala_type_to_ibis(tval): @@ -313,8 +314,7 @@ def _ibis_string_to_impala(tval): if tval in sql_type_names: return sql_type_names[tval] result = dt.validate_type(tval) - if result: - return repr(result) + return repr(result) if result else None _impala_to_ibis_type = { diff --git a/ibis/backends/mysql/__init__.py b/ibis/backends/mysql/__init__.py index d6c01fcac79c..c0ddacbd277f 100644 --- a/ibis/backends/mysql/__init__.py +++ b/ibis/backends/mysql/__init__.py @@ -110,14 +110,16 @@ def begin(self): previous_timezone = bind.execute('SELECT @@session.time_zone').scalar() try: bind.execute("SET @@session.time_zone = 'UTC'") - except Exception as e: - warnings.warn(f"Couldn't set mysql timezone: {str(e)}") + except Exception as e: # noqa: BLE001 + warnings.warn(f"Couldn't set MySQL timezone: {str(e)}") try: yield bind finally: - query = "SET @@session.time_zone = '{}'" - bind.execute(query.format(previous_timezone)) + try: + bind.execute(f"SET @@session.time_zone = '{previous_timezone}'") + except Exception as e: # noqa: BLE001 + warnings.warn(f"Couldn't reset MySQL timezone: {str(e)}") def _get_schema_using_query(self, query: str) -> sch.Schema: """Infer the schema of `query`.""" diff --git a/ibis/backends/mysql/tests/conftest.py b/ibis/backends/mysql/tests/conftest.py index 94ee7d782e7d..baa902f906b3 100644 --- a/ibis/backends/mysql/tests/conftest.py +++ b/ibis/backends/mysql/tests/conftest.py @@ -75,7 +75,7 @@ def _load_data( with open(script_dir / 'schema' / 'mysql.sql') as schema: engine = init_database( url=sa.engine.make_url( - f"mysql+pymysql://{user}:{password}@{host}:{port:d}?local_infile=1", # noqa: E501 + f"mysql+pymysql://{user}:{password}@{host}:{port:d}?local_infile=1", ), database=database, schema=schema, diff --git a/ibis/backends/pandas/client.py b/ibis/backends/pandas/client.py index 186651a21de2..dd91174f0873 100644 --- a/ibis/backends/pandas/client.py +++ b/ibis/backends/pandas/client.py @@ -64,11 +64,11 @@ def schema_from_series(s): @sch.infer.register(pd.DataFrame) -def infer_pandas_schema(df, schema=None): +def infer_pandas_schema(df: pd.DataFrame, schema=None): schema = schema if schema is not None else {} pairs = [] - for column_name in df.dtypes.keys(): + for column_name in df.dtypes.keys(): # noqa: SIM118 if not isinstance(column_name, str): raise TypeError('Column names must be strings to use the pandas backend') @@ -144,7 +144,7 @@ def convert_any_to_any(_, out_dtype, column): return column.map(date_parse) except TypeError: return column - except Exception: + except Exception: # noqa: BLE001 return column diff --git a/ibis/backends/pandas/execution/__init__.py b/ibis/backends/pandas/execution/__init__.py index f70ffe3f4ef7..5e6ee6a3be57 100644 --- a/ibis/backends/pandas/execution/__init__.py +++ b/ibis/backends/pandas/execution/__init__.py @@ -1,11 +1,11 @@ -from ibis.backends.pandas.execution.arrays import * # noqa: F401,F403 -from ibis.backends.pandas.execution.decimal import * # noqa: F401,F403 -from ibis.backends.pandas.execution.generic import * # noqa: F401,F403 -from ibis.backends.pandas.execution.join import * # noqa: F401,F403 -from ibis.backends.pandas.execution.maps import * # noqa: F401,F403 -from ibis.backends.pandas.execution.selection import * # noqa: F401,F403 -from ibis.backends.pandas.execution.strings import * # noqa: F401,F403 -from ibis.backends.pandas.execution.structs import * # noqa: F401,F403 -from ibis.backends.pandas.execution.temporal import * # noqa: F401,F403 -from ibis.backends.pandas.execution.timecontext import * # noqa: F401,F403 -from ibis.backends.pandas.execution.window import * # noqa: F401,F403 +from ibis.backends.pandas.execution.arrays import * # noqa: F403 +from ibis.backends.pandas.execution.decimal import * # noqa: F403 +from ibis.backends.pandas.execution.generic import * # noqa: F403 +from ibis.backends.pandas.execution.join import * # noqa: F403 +from ibis.backends.pandas.execution.maps import * # noqa: F403 +from ibis.backends.pandas.execution.selection import * # noqa: F403 +from ibis.backends.pandas.execution.strings import * # noqa: F403 +from ibis.backends.pandas.execution.structs import * # noqa: F403 +from ibis.backends.pandas.execution.temporal import * # noqa: F403 +from ibis.backends.pandas.execution.timecontext import * # noqa: F403 +from ibis.backends.pandas.execution.window import * # noqa: F403 diff --git a/ibis/backends/pandas/execution/generic.py b/ibis/backends/pandas/execution/generic.py index b2b8acf0ffe3..e6c9ae2a108c 100644 --- a/ibis/backends/pandas/execution/generic.py +++ b/ibis/backends/pandas/execution/generic.py @@ -1310,7 +1310,7 @@ def execute_table_array_view(op, _, **kwargs): @execute_node.register(ops.ZeroIfNull, pd.Series) def execute_zero_if_null_series(op, data, **kwargs): - zero = op.arg.output_dtype.to_pandas().type(0) + zero = op.arg.output_dtype.to_pandas().type(0) # noqa: UP003 return data.replace({np.nan: zero, None: zero, pd.NA: zero}) @@ -1320,5 +1320,5 @@ def execute_zero_if_null_series(op, data, **kwargs): ) def execute_zero_if_null_scalar(op, data, **kwargs): if data is None or pd.isna(data) or math.isnan(data) or np.isnan(data): - return op.arg.output_dtype.to_pandas().type(0) + return op.arg.output_dtype.to_pandas().type(0) # noqa: UP003 return data diff --git a/ibis/backends/postgres/registry.py b/ibis/backends/postgres/registry.py index e1a55d25468d..ab68031c4849 100644 --- a/ibis/backends/postgres/registry.py +++ b/ibis/backends/postgres/registry.py @@ -253,11 +253,10 @@ def _reduce_tokens(tokens, arg): # uninteresting text else: curtokens.append(token) - else: - # append result to r if we had more tokens or if we have no - # blacklisted tokens - if curtokens: - reduced.append(sa.func.to_char(arg, ''.join(curtokens))) + # append result to r if we had more tokens or if we have no + # blacklisted tokens + if curtokens: + reduced.append(sa.func.to_char(arg, ''.join(curtokens))) return reduced diff --git a/ibis/backends/postgres/tests/conftest.py b/ibis/backends/postgres/tests/conftest.py index 47ae28126aae..d97fdc5cf80e 100644 --- a/ibis/backends/postgres/tests/conftest.py +++ b/ibis/backends/postgres/tests/conftest.py @@ -86,7 +86,7 @@ def _load_data( # incurs an unnecessary round trip and requires more code: the # `data_iter` argument would have to be turned back into a CSV # before being passed to `copy_expert`. - sql = f"COPY {table} FROM STDIN WITH (FORMAT CSV, HEADER TRUE, DELIMITER ',')" # noqa: E501 + sql = f"COPY {table} FROM STDIN WITH (FORMAT CSV, HEADER TRUE, DELIMITER ',')" with data_dir.joinpath(f'{table}.csv').open('r') as file: cur.copy_expert(sql=sql, file=file) diff --git a/ibis/backends/postgres/tests/test_geospatial.py b/ibis/backends/postgres/tests/test_geospatial.py index eed9dbc2da3d..9d77305137d2 100644 --- a/ibis/backends/postgres/tests/test_geospatial.py +++ b/ibis/backends/postgres/tests/test_geospatial.py @@ -434,7 +434,7 @@ def test_geo_dataframe(geotable): ), ( "(((40.0 40.0, 20.0 45.0, 45.0 30.0, 40.0 40.0)), " - "((20.0 35.0, 10.0 30.0, 10.0 10.0, 30.0 5.0, 45.0 20.0, 20.0 35.0), " # noqa: E501 + "((20.0 35.0, 10.0 30.0, 10.0 10.0, 30.0 5.0, 45.0 20.0, 20.0 35.0), " "(30.0 20.0, 20.0 15.0, 20.0 25.0, 30.0 20.0)))" ), id="multipolygon", diff --git a/ibis/backends/pyspark/__init__.py b/ibis/backends/pyspark/__init__.py index bb47474d9c7b..67e184c2f6a4 100644 --- a/ibis/backends/pyspark/__init__.py +++ b/ibis/backends/pyspark/__init__.py @@ -453,7 +453,7 @@ def create_table( if force: mode = 'overwrite' spark_df.write.saveAsTable(table_name, format=format, mode=mode) - return + return None else: self._register_in_memory_tables(obj) @@ -628,4 +628,4 @@ def compute_stats( return self.raw_sql(stmt) def has_operation(cls, operation: type[ops.Value]) -> bool: - return operation in PySparkExprTranslator._registry.keys() + return operation in PySparkExprTranslator._registry diff --git a/ibis/backends/pyspark/client.py b/ibis/backends/pyspark/client.py index 087736525702..96ba86525546 100644 --- a/ibis/backends/pyspark/client.py +++ b/ibis/backends/pyspark/client.py @@ -112,7 +112,7 @@ def insert( if isinstance(obj, pd.DataFrame): spark_df = self._session.createDataFrame(obj) spark_df.insertInto(self.name, overwrite=overwrite) - return + return None expr = obj diff --git a/ibis/backends/pyspark/ddl.py b/ibis/backends/pyspark/ddl.py index 5f60b857c65c..500db7ae318b 100644 --- a/ibis/backends/pyspark/ddl.py +++ b/ibis/backends/pyspark/ddl.py @@ -15,7 +15,7 @@ def _sanitize_format(format): if format is None: - return + return None format = format.upper() format = _format_aliases.get(format, format) if format not in ( diff --git a/ibis/backends/snowflake/tests/conftest.py b/ibis/backends/snowflake/tests/conftest.py index ac794e12ee4b..a52bee9ccb51 100644 --- a/ibis/backends/snowflake/tests/conftest.py +++ b/ibis/backends/snowflake/tests/conftest.py @@ -66,7 +66,7 @@ def _load_data( src = data_dir / f"{table}.csv" con.execute(f"PUT file://{str(src.absolute())} @{stage}/{table}.csv") con.execute( - f"COPY INTO {table} FROM @{stage}/{table}.csv FILE_FORMAT = (FORMAT_NAME = ibis_csv_fmt)" # noqa: E501 + f"COPY INTO {table} FROM @{stage}/{table}.csv FILE_FORMAT = (FORMAT_NAME = ibis_csv_fmt)" ) @staticmethod @@ -75,3 +75,4 @@ def connect(data_directory: Path) -> BaseBackend: if snowflake_url := os.environ.get("SNOWFLAKE_URL"): return ibis.connect(snowflake_url) # type: ignore pytest.skip("SNOWFLAKE_URL environment variable is not defined") + return None diff --git a/ibis/backends/tests/base.py b/ibis/backends/tests/base.py index c2e742d6069c..e3a5242aed99 100644 --- a/ibis/backends/tests/base.py +++ b/ibis/backends/tests/base.py @@ -180,6 +180,7 @@ def struct(self) -> Optional[ir.Table]: return self.connection.table("struct") else: pytest.xfail(f"{self.name()} backend does not support struct types") + return None @property def json_t(self) -> Optional[ir.Table]: @@ -189,6 +190,7 @@ def json_t(self) -> Optional[ir.Table]: return self.connection.table("json_t").mutate(js=_.js.cast("json")) else: pytest.xfail(f"{self.name()} backend does not support json types") + return None @property def api(self): diff --git a/ibis/backends/tests/test_array.py b/ibis/backends/tests/test_array.py index c3b69c897471..ab612d9c025c 100644 --- a/ibis/backends/tests/test_array.py +++ b/ibis/backends/tests/test_array.py @@ -120,7 +120,7 @@ def test_array_index(con, idx): ), pytest.mark.never( ["snowflake"], - reason="snowflake has an extremely specialized way of implementing arrays", # noqa: E501 + reason="snowflake has an extremely specialized way of implementing arrays", ), # someone just needs to implement these pytest.mark.notimpl(["datafusion", "dask"]), diff --git a/ibis/backends/tests/test_set_ops.py b/ibis/backends/tests/test_set_ops.py index d492d47c8425..dfa9d4a98b1e 100644 --- a/ibis/backends/tests/test_set_ops.py +++ b/ibis/backends/tests/test_set_ops.py @@ -8,13 +8,13 @@ @pytest.fixture def union_subsets(alltypes, df): - a = alltypes.filter((5200 <= _.id) & (_.id <= 5210)) - b = alltypes.filter((5205 <= _.id) & (_.id <= 5215)) - c = alltypes.filter((5213 <= _.id) & (_.id <= 5220)) + a = alltypes.filter((_.id >= 5200) & (_.id <= 5210)) + b = alltypes.filter((_.id >= 5205) & (_.id <= 5215)) + c = alltypes.filter((_.id >= 5213) & (_.id <= 5220)) - da = df[(5200 <= df.id) & (df.id <= 5210)] - db = df[(5205 <= df.id) & (df.id <= 5215)] - dc = df[(5213 <= df.id) & (df.id <= 5220)] + da = df[(df.id >= 5200) & (df.id <= 5210)] + db = df[(df.id >= 5205) & (df.id <= 5215)] + dc = df[(df.id >= 5213) & (df.id <= 5220)] return (a, b, c), (da, db, dc) @@ -68,15 +68,15 @@ def test_union_mixed_distinct(backend, union_subsets): @pytest.mark.notimpl(["datafusion", "polars"]) @pytest.mark.notyet(["impala"]) def test_intersect(backend, alltypes, df, distinct): - a = alltypes.filter((5200 <= _.id) & (_.id <= 5210)) - b = alltypes.filter((5205 <= _.id) & (_.id <= 5215)) - c = alltypes.filter((5195 <= _.id) & (_.id <= 5208)) + a = alltypes.filter((_.id >= 5200) & (_.id <= 5210)) + b = alltypes.filter((_.id >= 5205) & (_.id <= 5215)) + c = alltypes.filter((_.id >= 5195) & (_.id <= 5208)) # Reset index to ensure simple RangeIndex, needed for computing `expected` df = df.reset_index(drop=True) - da = df[(5200 <= df.id) & (df.id <= 5210)] - db = df[(5205 <= df.id) & (df.id <= 5215)] - dc = df[(5195 <= df.id) & (df.id <= 5208)] + da = df[(df.id >= 5200) & (df.id <= 5210)] + db = df[(df.id >= 5205) & (df.id <= 5215)] + dc = df[(df.id >= 5195) & (df.id <= 5208)] expr = ibis.intersect(a, b, c, distinct=distinct).order_by("id") result = expr.execute() @@ -106,15 +106,15 @@ def test_intersect(backend, alltypes, df, distinct): @pytest.mark.notimpl(["datafusion", "polars"]) @pytest.mark.notyet(["impala"]) def test_difference(backend, alltypes, df, distinct): - a = alltypes.filter((5200 <= _.id) & (_.id <= 5210)) - b = alltypes.filter((5205 <= _.id) & (_.id <= 5215)) - c = alltypes.filter((5195 <= _.id) & (_.id <= 5202)) + a = alltypes.filter((_.id >= 5200) & (_.id <= 5210)) + b = alltypes.filter((_.id >= 5205) & (_.id <= 5215)) + c = alltypes.filter((_.id >= 5195) & (_.id <= 5202)) # Reset index to ensure simple RangeIndex, needed for computing `expected` df = df.reset_index(drop=True) - da = df[(5200 <= df.id) & (df.id <= 5210)] - db = df[(5205 <= df.id) & (df.id <= 5215)] - dc = df[(5195 <= df.id) & (df.id <= 5202)] + da = df[(df.id >= 5200) & (df.id <= 5210)] + db = df[(df.id >= 5205) & (df.id <= 5215)] + dc = df[(df.id >= 5195) & (df.id <= 5202)] expr = ibis.difference(a, b, c, distinct=distinct).order_by("id") result = expr.execute() diff --git a/ibis/common/parsing.py b/ibis/common/parsing.py index cf2e3e7a6362..7b20e4b819e7 100644 --- a/ibis/common/parsing.py +++ b/ibis/common/parsing.py @@ -3,7 +3,9 @@ import parsy -_STRING_REGEX = """('[^\n'\\\\]*(?:\\\\.[^\n'\\\\]*)*'|"[^\n"\\\\"]*(?:\\\\.[^\n"\\\\]*)*")""" # noqa: E501 +_STRING_REGEX = ( + """('[^\n'\\\\]*(?:\\\\.[^\n'\\\\]*)*'|"[^\n"\\\\"]*(?:\\\\.[^\n"\\\\]*)*")""" +) SPACES = parsy.regex(r'\s*', re.MULTILINE) diff --git a/ibis/common/tests/test_annotations.py b/ibis/common/tests/test_annotations.py index fff28e75191e..a10b549df3a4 100644 --- a/ibis/common/tests/test_annotations.py +++ b/ibis/common/tests/test_annotations.py @@ -263,7 +263,9 @@ def endswith_d(x, this): def test_annotated_function_with_complex_type_annotations(): @annotated - def test(a: Annotated[str, short_str, endswith_d], b: Union[int, float]): + def test( + a: Annotated[str, short_str, endswith_d], b: Union[int, float] # noqa: UP007 + ): return a, b assert test("abcd", 1) == ("abcd", 1) diff --git a/ibis/common/tests/test_grounds.py b/ibis/common/tests/test_grounds.py index 703049bbd6ef..ba4fc4669e46 100644 --- a/ibis/common/tests/test_grounds.py +++ b/ibis/common/tests/test_grounds.py @@ -428,7 +428,7 @@ class Sum(VersionedOp, Reduction): assert ( str(Sum.__signature__) - == "(arg: instance_of(,), version: instance_of(,), where: option(instance_of(,),default=False) = None)" # noqa: E501 + == "(arg: instance_of(,), version: instance_of(,), where: option(instance_of(,),default=False) = None)" ) @@ -446,7 +446,7 @@ class Between(Value, ConditionalOp): assert ( str(Between.__signature__) - == "(min: instance_of(,), max: instance_of(,), how: option(instance_of(,),default='strict') = None, where: option(instance_of(,),default=False) = None)" # noqa: E501 + == "(min: instance_of(,), max: instance_of(,), how: option(instance_of(,),default='strict') = None, where: option(instance_of(,),default=False) = None)" ) diff --git a/ibis/expr/api.py b/ibis/expr/api.py index 8c9adb201d39..f18f5a431ae2 100644 --- a/ibis/expr/api.py +++ b/ibis/expr/api.py @@ -26,77 +26,13 @@ from ibis.expr.deferred import Deferred from ibis.expr.schema import Schema from ibis.expr.sql import parse_sql, show_sql, to_sql -from ibis.expr.types import ( # noqa: F401 - ArrayColumn, - ArrayScalar, - ArrayValue, - BooleanColumn, - BooleanScalar, - BooleanValue, - CategoryScalar, - CategoryValue, - Column, - DateColumn, - DateScalar, +from ibis.expr.types import ( DateValue, - DecimalColumn, - DecimalScalar, - DecimalValue, Expr, - FloatingColumn, - FloatingScalar, - FloatingValue, - GeoSpatialColumn, - GeoSpatialScalar, - GeoSpatialValue, IntegerColumn, - IntegerScalar, - IntegerValue, - IntervalColumn, - IntervalScalar, - IntervalValue, - LineStringColumn, - LineStringScalar, - LineStringValue, - MapColumn, - MapScalar, - MapValue, - MultiLineStringColumn, - MultiLineStringScalar, - MultiLineStringValue, - MultiPointColumn, - MultiPointScalar, - MultiPointValue, - MultiPolygonColumn, - MultiPolygonScalar, - MultiPolygonValue, - NullColumn, - NullScalar, - NullValue, - NumericColumn, - NumericScalar, - NumericValue, - PointColumn, - PointScalar, - PointValue, - PolygonColumn, - PolygonScalar, - PolygonValue, - Scalar, - StringColumn, - StringScalar, StringValue, - StructColumn, - StructScalar, - StructValue, Table, - TimeColumn, - TimeScalar, - TimestampColumn, - TimestampScalar, - TimestampValue, TimeValue, - Value, array, literal, map, @@ -855,7 +791,7 @@ def case() -> bl.SearchedCaseBuilder: ------- SearchedCaseBuilder A builder object to use for constructing a case expression. - """ # noqa: E501 + """ return bl.SearchedCaseBuilder() diff --git a/ibis/expr/operations/__init__.py b/ibis/expr/operations/__init__.py index a72815e73e69..ddd4cebf708b 100644 --- a/ibis/expr/operations/__init__.py +++ b/ibis/expr/operations/__init__.py @@ -1,17 +1,17 @@ -from ibis.expr.operations.analytic import * # noqa: F401,F403 -from ibis.expr.operations.arrays import * # noqa: F401,F403 -from ibis.expr.operations.core import * # noqa: F401,F403 -from ibis.expr.operations.generic import * # noqa: F401,F403 -from ibis.expr.operations.geospatial import * # noqa: F401,F403 -from ibis.expr.operations.histograms import * # noqa: F401,F403 -from ibis.expr.operations.json import * # noqa: F401,F403 -from ibis.expr.operations.logical import * # noqa: F401,F403 -from ibis.expr.operations.maps import * # noqa: F401,F403 -from ibis.expr.operations.numeric import * # noqa: F401,F403 -from ibis.expr.operations.reductions import * # noqa: F401,F403 -from ibis.expr.operations.relations import * # noqa: F401,F403 -from ibis.expr.operations.sortkeys import * # noqa: F401,F403 -from ibis.expr.operations.strings import * # noqa: F401,F403 -from ibis.expr.operations.structs import * # noqa: F401,F403 -from ibis.expr.operations.temporal import * # noqa: F401,F403 -from ibis.expr.operations.vectorized import * # noqa: F401,F403 +from ibis.expr.operations.analytic import * # noqa: F403 +from ibis.expr.operations.arrays import * # noqa: F403 +from ibis.expr.operations.core import * # noqa: F403 +from ibis.expr.operations.generic import * # noqa: F403 +from ibis.expr.operations.geospatial import * # noqa: F403 +from ibis.expr.operations.histograms import * # noqa: F403 +from ibis.expr.operations.json import * # noqa: F403 +from ibis.expr.operations.logical import * # noqa: F403 +from ibis.expr.operations.maps import * # noqa: F403 +from ibis.expr.operations.numeric import * # noqa: F403 +from ibis.expr.operations.reductions import * # noqa: F403 +from ibis.expr.operations.relations import * # noqa: F403 +from ibis.expr.operations.sortkeys import * # noqa: F403 +from ibis.expr.operations.strings import * # noqa: F403 +from ibis.expr.operations.structs import * # noqa: F403 +from ibis.expr.operations.temporal import * # noqa: F403 +from ibis.expr.operations.vectorized import * # noqa: F403 diff --git a/ibis/expr/operations/geospatial.py b/ibis/expr/operations/geospatial.py index 994f6ccd7f25..55597e2fc412 100644 --- a/ibis/expr/operations/geospatial.py +++ b/ibis/expr/operations/geospatial.py @@ -100,7 +100,7 @@ class GeoGeometryType(GeoSpatialUnOp): class GeoIntersects(GeoSpatialBinOp): """Returns True if the Geometries/Geography “spatially intersect in 2D” - - (share any portion of space) and False if they don’t (they are Disjoint). + - (share any portion of space) and False if they don`t (they are Disjoint). """ output_dtype = dt.boolean diff --git a/ibis/expr/operations/reductions.py b/ibis/expr/operations/reductions.py index f4f6546c9f7a..9b148095f849 100644 --- a/ibis/expr/operations/reductions.py +++ b/ibis/expr/operations/reductions.py @@ -50,7 +50,7 @@ class BitAnd(Filterable, Reduction): * BigQuery [`BIT_AND`](https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#bit_and) * MySQL [`BIT_AND`](https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_bit-and) - """ # noqa: E501 + """ arg = rlz.column(rlz.integer) output_dtype = rlz.dtype_like('arg') @@ -67,7 +67,7 @@ class BitOr(Filterable, Reduction): * BigQuery [`BIT_OR`](https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#bit_or) * MySQL [`BIT_OR`](https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_bit-or) - """ # noqa: E501 + """ arg = rlz.column(rlz.integer) output_dtype = rlz.dtype_like('arg') @@ -84,7 +84,7 @@ class BitXor(Filterable, Reduction): * BigQuery [`BIT_XOR`](https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#bit_xor) * MySQL [`BIT_XOR`](https://dev.mysql.com/doc/refman/5.7/en/aggregate-functions.html#function_bit-xor) - """ # noqa: E501 + """ arg = rlz.column(rlz.integer) output_dtype = rlz.dtype_like('arg') diff --git a/ibis/expr/rules.py b/ibis/expr/rules.py index 4267e84d73ef..8c4f1d3539c7 100644 --- a/ibis/expr/rules.py +++ b/ibis/expr/rules.py @@ -9,18 +9,13 @@ import ibis.expr.types as ir import ibis.util as util from ibis.common.annotations import attribute, optional # noqa: F401 -from ibis.common.validators import ( # noqa: F401 - bool_, - instance_of, - isin, - lazy_instance_of, - map_to, - one_of, - ref, - str_, - tuple_of, - validator, -) +from ibis.common.validators import bool_ # noqa: F401 +from ibis.common.validators import isin # noqa: F401 +from ibis.common.validators import lazy_instance_of # noqa: F401 +from ibis.common.validators import ref # noqa: F401 +from ibis.common.validators import str_ # noqa: F401 +from ibis.common.validators import tuple_of # noqa: F401 +from ibis.common.validators import instance_of, map_to, one_of, validator from ibis.expr.deferred import Deferred diff --git a/ibis/expr/schema.py b/ibis/expr/schema.py index 30edb673dfdb..1c7ae4836929 100644 --- a/ibis/expr/schema.py +++ b/ibis/expr/schema.py @@ -58,7 +58,7 @@ def _name_locs(self) -> dict[str, int]: name_locs = {v: i for i, v in enumerate(self.names)} if len(name_locs) < len(self.names): duplicate_names = list(self.names) - for v in name_locs.keys(): + for v in name_locs: duplicate_names.remove(v) raise IntegrityError(f'Duplicate column name(s): {duplicate_names}') return name_locs diff --git a/ibis/expr/sql.py b/ibis/expr/sql.py index 81f28532ada1..b027a151fe58 100644 --- a/ibis/expr/sql.py +++ b/ibis/expr/sql.py @@ -44,7 +44,7 @@ class Catalog(Dict[str, sch.Schema]): dt.Geometry: "geometry", } - def to_sqlglot_schema(self, schema: sch.Schema) -> Dict[str, str]: + def to_sqlglot_schema(self, schema: sch.Schema) -> dict[str, str]: return { name: self.typemap.get(type(dtype), str(dtype)) for name, dtype in schema.items() diff --git a/ibis/expr/timecontext.py b/ibis/expr/timecontext.py index 68f75a162aba..18442f68f2eb 100644 --- a/ibis/expr/timecontext.py +++ b/ibis/expr/timecontext.py @@ -39,7 +39,6 @@ import ibis.common.exceptions as com import ibis.config as config -import ibis.expr.api as ir import ibis.expr.operations as ops if TYPE_CHECKING: @@ -310,6 +309,8 @@ def adjust_context_asof_join( def adjust_context_window( op: ops.Window, scope: Scope, timecontext: TimeContext ) -> TimeContext: + import ibis.expr.types as ir + # adjust time context by preceding and following begin, end = timecontext diff --git a/ibis/expr/types/__init__.py b/ibis/expr/types/__init__.py index 865810336850..3f5c5252ddf2 100644 --- a/ibis/expr/types/__init__.py +++ b/ibis/expr/types/__init__.py @@ -1,17 +1,17 @@ -from ibis.expr.types.arrays import * # noqa: F401,F403 -from ibis.expr.types.binary import * # noqa: F401,F403 -from ibis.expr.types.category import * # noqa: F401,F403 -from ibis.expr.types.collections import * # noqa: F401,F403 -from ibis.expr.types.core import * # noqa: F401,F403 -from ibis.expr.types.generic import * # noqa: F401,F403 -from ibis.expr.types.geospatial import * # noqa: F401,F403 -from ibis.expr.types.inet import * # noqa: F401,F403 -from ibis.expr.types.json import * # noqa: F401,F403 -from ibis.expr.types.logical import * # noqa: F401,F403 -from ibis.expr.types.maps import * # noqa: F401,F403 -from ibis.expr.types.numeric import * # noqa: F401,F403 -from ibis.expr.types.relations import * # noqa: F401,F403 -from ibis.expr.types.strings import * # noqa: F401,F403 -from ibis.expr.types.structs import * # noqa: F401,F403 -from ibis.expr.types.temporal import * # noqa: F401,F403 -from ibis.expr.types.uuid import * # noqa: F401,F403 +from ibis.expr.types.arrays import * # noqa: F403 +from ibis.expr.types.binary import * # noqa: F403 +from ibis.expr.types.category import * # noqa: F403 +from ibis.expr.types.collections import * # noqa: F403 +from ibis.expr.types.core import * # noqa: F403 +from ibis.expr.types.generic import * # noqa: F403 +from ibis.expr.types.geospatial import * # noqa: F403 +from ibis.expr.types.inet import * # noqa: F403 +from ibis.expr.types.json import * # noqa: F403 +from ibis.expr.types.logical import * # noqa: F403 +from ibis.expr.types.maps import * # noqa: F403 +from ibis.expr.types.numeric import * # noqa: F403 +from ibis.expr.types.relations import * # noqa: F403 +from ibis.expr.types.strings import * # noqa: F403 +from ibis.expr.types.structs import * # noqa: F403 +from ibis.expr.types.temporal import * # noqa: F403 +from ibis.expr.types.uuid import * # noqa: F403 diff --git a/ibis/expr/types/core.py b/ibis/expr/types/core.py index 37b49d314039..1cbc7d88259a 100644 --- a/ibis/expr/types/core.py +++ b/ibis/expr/types/core.py @@ -1,5 +1,6 @@ from __future__ import annotations +import contextlib import os import webbrowser from typing import TYPE_CHECKING, Any, Mapping @@ -88,12 +89,10 @@ def _repr_png_(self) -> bytes | None: except ImportError: return None else: - try: + # Something may go wrong, and we can't error in the notebook + # so fallback to the default text representation. + with contextlib.suppress(Exception): return viz.to_graph(self).pipe(format='png') - except Exception: - # Something may go wrong, and we can't error in the notebook - # so fallback to the default text representation. - return None def visualize( self, diff --git a/ibis/expr/types/groupby.py b/ibis/expr/types/groupby.py index d4f27ad32c3f..31c53d49c4ac 100644 --- a/ibis/expr/types/groupby.py +++ b/ibis/expr/types/groupby.py @@ -183,7 +183,7 @@ def mutate( ------- Table A table expression with window functions applied - """ # noqa: E501 + """ if exprs is None: exprs = [] else: diff --git a/ibis/expr/types/pretty.py b/ibis/expr/types/pretty.py index 6a00ca0c31a6..e71427f9dfdf 100644 --- a/ibis/expr/types/pretty.py +++ b/ibis/expr/types/pretty.py @@ -169,7 +169,7 @@ def isnull(x): try: max_width = max(map(len, out)) - except Exception: + except Exception: # noqa: BLE001 max_width = None min_width = 20 else: diff --git a/ibis/expr/visualize.py b/ibis/expr/visualize.py index 872a91e8b897..b5eac5bb0313 100644 --- a/ibis/expr/visualize.py +++ b/ibis/expr/visualize.py @@ -124,7 +124,7 @@ def to_graph(expr, node_attr=None, edge_attr=None, label_edges: bool = False): def draw(graph, path=None, format='png', verbose: bool = False): if verbose: - print(graph.source, file=sys.stderr) + print(graph.source, file=sys.stderr) # noqa: T201 piped_source = graph.pipe(format=format) diff --git a/ibis/tests/expr/test_table.py b/ibis/tests/expr/test_table.py index 5ed9f51fcfc7..04f4a7d86029 100644 --- a/ibis/tests/expr/test_table.py +++ b/ibis/tests/expr/test_table.py @@ -9,7 +9,6 @@ import ibis import ibis.common.exceptions as com -import ibis.config as config import ibis.expr.analysis as an import ibis.expr.api as api import ibis.expr.datatypes as dt @@ -174,18 +173,6 @@ def test_projection_invalid_root(table): left.projection(exprs) -def test_projection_unnamed_literal_interactive_blowup(con): - # #147 and #153 alike - table = con.table('functional_alltypes') - exprs = [table.bigint_col, ibis.literal(5)] - - with config.option_context('interactive', True): - try: - table.select(exprs) - except Exception as e: - assert 'named' in e.args[0] - - def test_projection_with_star_expr(table): new_expr = (table['a'] * 5).name('bigger_a') diff --git a/ibis/tests/expr/test_value_exprs.py b/ibis/tests/expr/test_value_exprs.py index a4e81b7c8560..bb6ecfbd86ef 100644 --- a/ibis/tests/expr/test_value_exprs.py +++ b/ibis/tests/expr/test_value_exprs.py @@ -1635,7 +1635,7 @@ def test_logical_comparison_rlz_incompatible_error(table, operation): def test_case_rlz_incompatible_error(table): with pytest.raises(TypeError, match=r"a:int8 and Literal\(foo\):string"): - "foo" == table.a + table.a == 'foo' @pytest.mark.parametrize("func", [ibis.asc, ibis.desc]) diff --git a/justfile b/justfile index 62eef68255e2..26c6e38c1af5 100644 --- a/justfile +++ b/justfile @@ -17,10 +17,9 @@ lock: # format code fmt: - absolufy-imports ibis/**/*.py + ruff --fix . black . isort . - pyupgrade --py38-plus --keep-runtime-typing ibis/**/*.py # run all non-backend tests; additional arguments are forwarded to pytest check *args: @@ -34,7 +33,7 @@ ci-check *args: lint: black -q . --check isort -q . --check - flake8 --exclude ibis/tests/sql/snapshots/ . + ruff . # run the test suite for one or more backends test +backends: diff --git a/poetry.lock b/poetry.lock index f0ca79cfed77..0694b4629661 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,17 +1,5 @@ # This file is automatically @generated by Poetry and should not be changed by hand. -[[package]] -name = "absolufy-imports" -version = "0.3.1" -description = "A tool to automatically replace relative imports with absolute ones." -category = "dev" -optional = false -python-versions = ">=3.6.1" -files = [ - {file = "absolufy_imports-0.3.1-py2.py3-none-any.whl", hash = "sha256:49bf7c753a9282006d553ba99217f48f947e3eef09e18a700f8a82f75dc7fc5c"}, - {file = "absolufy_imports-0.3.1.tar.gz", hash = "sha256:c90638a6c0b66826d1fb4880ddc20ef7701af34192c94faf40b95d32b59f9793"}, -] - [[package]] name = "appnope" version = "0.1.3" @@ -1247,60 +1235,6 @@ calc = ["shapely"] s3 = ["boto3 (>=1.2.4)"] test = ["boto3 (>=1.2.4)", "mock", "pytest (>=3)", "pytest-cov"] -[[package]] -name = "flake8" -version = "5.0.4" -description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" -optional = false -python-versions = ">=3.6.1" -files = [ - {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, - {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.9.0,<2.10.0" -pyflakes = ">=2.5.0,<2.6.0" - -[[package]] -name = "flake8" -version = "6.0.0" -description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "flake8-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"}, - {file = "flake8-6.0.0.tar.gz", hash = "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.10.0,<2.11.0" -pyflakes = ">=3.0.0,<3.1.0" - -[[package]] -name = "flake8-noqa" -version = "1.3.0" -description = "Flake8 noqa comment validation" -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "flake8-noqa-1.3.0.tar.gz", hash = "sha256:da613a371370373283c446da8067ff9d6a9b5c4e5b1f49ed6a32f7fa653c1f51"}, - {file = "flake8_noqa-1.3.0-py3-none-any.whl", hash = "sha256:64a3c5febf382e1b3d517fb0b7adb0090246112b39fd65e8607bbb0e785f94f0"}, -] - -[package.dependencies] -flake8 = ">=3.8.0,<7.0" -typing-extensions = ">=3.7.4.2" - -[package.extras] -dev = ["flake8 (>=3.8.0,<6.0.0)", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-modern-annotations", "flake8-noqa", "flake8-polyfill", "flake8-pyproject", "flake8-requirements", "flake8-typechecking-import", "flake8-use-fstring", "mypy", "pep8-naming"] -test = ["flake8-docstrings"] - [[package]] name = "fsspec" version = "2022.11.0" @@ -2425,18 +2359,6 @@ files = [ [package.dependencies] traitlets = "*" -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - [[package]] name = "mdit-py-plugins" version = "0.3.3" @@ -3462,30 +3384,6 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6,<0.5.0" -[[package]] -name = "pycodestyle" -version = "2.9.1" -description = "Python style guide checker" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pycodestyle-2.9.1-py2.py3-none-any.whl", hash = "sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b"}, - {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, -] - -[[package]] -name = "pycodestyle" -version = "2.10.0" -description = "Python style guide checker" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, - {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"}, -] - [[package]] name = "pycparser" version = "2.21" @@ -3551,30 +3449,6 @@ google-auth = {version = ">=1.25.0,<3.0dev", markers = "python_version >= \"3.6\ google-auth-oauthlib = {version = ">=0.4.0", markers = "python_version >= \"3.6\""} setuptools = "*" -[[package]] -name = "pyflakes" -version = "2.5.0" -description = "passive checker of Python programs" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, - {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, -] - -[[package]] -name = "pyflakes" -version = "3.0.1" -description = "passive checker of Python programs" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, - {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, -] - [[package]] name = "pygments" version = "2.13.0" @@ -4091,21 +3965,6 @@ files = [ "backports.zoneinfo" = {version = "*", markers = "python_version >= \"3.6\" and python_version < \"3.9\""} tzdata = {version = "*", markers = "python_version >= \"3.6\""} -[[package]] -name = "pyupgrade" -version = "3.3.1" -description = "A tool to automatically upgrade syntax for newer versions." -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pyupgrade-3.3.1-py2.py3-none-any.whl", hash = "sha256:3b93641963df022d605c78aeae4b5956a5296ea24701eafaef9c487527b77e60"}, - {file = "pyupgrade-3.3.1.tar.gz", hash = "sha256:f88bce38b0ba92c2a9a5063c8629e456e8d919b67d2d42c7ecab82ff196f9813"}, -] - -[package.dependencies] -tokenize-rt = ">=3.2.0" - [[package]] name = "pywin32" version = "305" @@ -4457,6 +4316,32 @@ files = [ [package.dependencies] pyasn1 = ">=0.1.3" +[[package]] +name = "ruff" +version = "0.0.189" +description = "An extremely fast Python linter, written in Rust." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.0.189-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:07c947b42d3c5efc6761214acdb6b71a49b833ad9fb9b320454244a6fe01f212"}, + {file = "ruff-0.0.189-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:76e6161d021bde5738bf9d123ae445cb3a22fa60f14958ce64961d8af16141a0"}, + {file = "ruff-0.0.189-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c27f51e5b48cd483459cdd1c95a6bd989adcf7653ccc440ca437f4993fe4b812"}, + {file = "ruff-0.0.189-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e89f488a16ce2b21d940fc6271ed161affec788955f7b41761a9693a92e994bb"}, + {file = "ruff-0.0.189-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fee593d8d470811c316ff2eb0124ac74668a3d637ab3fb237aa3fa8561fb89aa"}, + {file = "ruff-0.0.189-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:bc3a73683a5b3b4b7bf951bbd4aa7d79b993c8c2e608a68de120c342ebe510f2"}, + {file = "ruff-0.0.189-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e5d73877558651f48c86d958afe0f662b6c3639990c230a6b9d82ac6093484db"}, + {file = "ruff-0.0.189-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d1e6e9813f59ba54e7cb6f28c1f2a9a756197f6e321bd68519afe57f8522fce"}, + {file = "ruff-0.0.189-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d177090cf03004b14814b0aad530758f5186d391250afb737570edd55beabc6"}, + {file = "ruff-0.0.189-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:48de3253856a0a85f9b53a0ca1982946c7fd343c796cdc76ece0ae359d5b71b5"}, + {file = "ruff-0.0.189-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e935bb5a213030de312ad00df477f38c78ac97af58b0e6a4ae5762705a5113da"}, + {file = "ruff-0.0.189-py3-none-musllinux_1_2_i686.whl", hash = "sha256:bdb8173d6efff96e0cc5fe38f5fc4daa0d28fb11553482b9989d372fdafc7708"}, + {file = "ruff-0.0.189-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:14486fd8632bc4c7f926137a9c6a8c45993ff6667ddb7a88192c369c3afd86e9"}, + {file = "ruff-0.0.189-py3-none-win32.whl", hash = "sha256:e281080e2ed04f01275b3df5baa0afe2802ab145349298e24700cdd09c0afddc"}, + {file = "ruff-0.0.189-py3-none-win_amd64.whl", hash = "sha256:c552ff0b0587a5e13f935131d2a19782c0baf8b59175cf3160a76545fbdbdd76"}, + {file = "ruff-0.0.189.tar.gz", hash = "sha256:90a3031461ed83686ff78f96e58d28cdee835110c51bdfa0968a2d5892610c71"}, +] + [[package]] name = "setuptools" version = "65.6.3" @@ -4677,7 +4562,7 @@ greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platfo [package.extras] aiomysql = ["aiomysql", "greenlet (!=0.4.17)"] -aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] +aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing-extensions (!=3.10.0.1)"] asyncio = ["greenlet (!=0.4.17)"] asyncmy = ["asyncmy (>=0.2.3,!=0.2.4)", "greenlet (!=0.4.17)"] mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2)"] @@ -4687,14 +4572,14 @@ mssql-pyodbc = ["pyodbc"] mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"] mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"] mysql-connector = ["mysql-connector-python"] -oracle = ["cx_oracle (>=7)", "cx_oracle (>=7,<8)"] +oracle = ["cx-oracle (>=7)", "cx-oracle (>=7,<8)"] postgresql = ["psycopg2 (>=2.7)"] postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] postgresql-psycopg2binary = ["psycopg2-binary"] postgresql-psycopg2cffi = ["psycopg2cffi"] pymysql = ["pymysql", "pymysql (<1)"] -sqlcipher = ["sqlcipher3_binary"] +sqlcipher = ["sqlcipher3-binary"] [[package]] name = "sqlglot" @@ -4813,18 +4698,6 @@ webencodings = ">=0.4" doc = ["sphinx", "sphinx_rtd_theme"] test = ["flake8", "isort", "pytest"] -[[package]] -name = "tokenize-rt" -version = "5.0.0" -description = "A wrapper around the stdlib `tokenize` which roundtrips." -category = "dev" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tokenize_rt-5.0.0-py2.py3-none-any.whl", hash = "sha256:c67772c662c6b3dc65edf66808577968fb10badfc2042e3027196bed4daf9e5a"}, - {file = "tokenize_rt-5.0.0.tar.gz", hash = "sha256:3160bc0c3e8491312d0485171dea861fc160a240f5f5766b72a1165408d10740"}, -] - [[package]] name = "toml" version = "0.10.2" @@ -5143,4 +5016,4 @@ visualization = ["graphviz"] [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "9d48d707ebcc0b09f1b57bd4258e9e05e21f9b9acccc72582fe63865a8bc9a3e" +content-hash = "1e8421da119d6a50a5e6e01a0c86e2283e542c946e3ab4c6f6058e64ad226069" diff --git a/pyproject.toml b/pyproject.toml index 3ab66659e1e6..105316f1bd18 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,18 +70,12 @@ trino = { version = ">=0.319,<1", optional = true, extras = ["sqlalchemy"] } snowflake-sqlalchemy = { version = ">=1.4.1,<2", optional = true } [tool.poetry.group.dev.dependencies] -absolufy-imports = ">=0.3.1,<1" black = ">=22.1.0,<23" docformatter = ">=1.5.0,<2" -flake8 = [ - { version = ">=5,<7", python = ">=3.8.1" }, - { version = ">=5,<6", python = "<3.8.1" } -] -flake8-noqa = ">=1.3.0,<2" ipython = ">=7.27.0,<9" isort = ">=5.9.3,<6" poetry-dynamic-versioning = ">=0.18.0,<1" -pyupgrade = ">=2.26.0,<4" +ruff = ">=0.0.189,<1" [tool.poetry.group.test.dependencies] black = ">=22.1.0,<23" @@ -289,6 +283,32 @@ markers = [ "trino: Trino tests", ] +[tool.ruff] +line-length = 88 +select = [ + "E", # pycodestyle + "W", # pycodestyle + "F", # pyflakes + "UP", # pyupgrade + "RUF", # ruff-specific rules + "TID", # flake8-tidy-imports + "T10", # flake8-debugger + "PGH", # pygrep-hooks + "PLC", # pylint + "PLE", # pylint + "PLW", # pylint + "SIM", # flake8-simplify + "T20", # flake8-print + "ICN", # flake8-import-conventions + "RET", # flake8-return + "BLE", # flake8-blind-except + +] +respect-gitignore = true +ignore = ["E501", "PGH003", "RET504", "RET505", "RET506", "RET507", "RET508"] +exclude = ["**/*_py310.py", "ibis/tests/*/snapshots/*"] +target-version = "py38" + [tool.black] line_length = 88 skip_string_normalization = true diff --git a/requirements.txt b/requirements.txt index e8e3b153aa93..2e4f1f435d04 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,3 @@ -absolufy-imports==0.3.1 ; python_version >= "3.8" and python_version < "4.0" appnope==0.1.3 ; python_version >= "3.8" and python_version < "4.0" and sys_platform == "darwin" or python_version >= "3.8" and python_version < "4.0" and platform_system == "Darwin" asttokens==2.2.1 ; python_version >= "3.8" and python_version < "4.0" astunparse==1.6.3 ; python_version >= "3.8" and python_version < "3.9" @@ -28,9 +27,6 @@ execnet==1.9.0 ; python_version >= "3.8" and python_version < "4.0" executing==1.2.0 ; python_version >= "3.8" and python_version < "4.0" fastjsonschema==2.16.2 ; python_version >= "3.8" and python_version < "4.0" filelock==3.8.2 ; python_version >= "3.8" and python_version < "4.0" -flake8-noqa==1.3.0 ; python_version >= "3.8" and python_version < "4.0" -flake8==5.0.4 ; python_version >= "3.8" and python_full_version < "3.8.1" -flake8==6.0.0 ; python_full_version >= "3.8.1" and python_version < "4.0" ghp-import==2.1.0 ; python_version >= "3.8" and python_version < "4.0" gitdb==4.0.10 ; python_version >= "3.8" and python_version < "4.0" gitpython==3.1.29 ; python_version >= "3.8" and python_version < "4.0" @@ -55,7 +51,6 @@ markdown-it-py==2.1.0 ; python_version >= "3.8" and python_version < "4.0" markdown==3.3.7 ; python_version >= "3.8" and python_version < "4.0" markupsafe==2.1.1 ; python_version >= "3.8" and python_version < "4.0" matplotlib-inline==0.1.6 ; python_version >= "3.8" and python_version < "4.0" -mccabe==0.7.0 ; python_version >= "3.8" and python_version < "4.0" mdit-py-plugins==0.3.3 ; python_version >= "3.8" and python_version < "4.0" mdurl==0.1.2 ; python_version >= "3.8" and python_version < "4.0" mergedeep==1.3.4 ; python_version >= "3.8" and python_version < "4.0" @@ -100,11 +95,7 @@ pure-eval==0.2.2 ; python_version >= "3.8" and python_version < "4.0" py-cpuinfo==9.0.0 ; python_version >= "3.8" and python_version < "4.0" py==1.11.0 ; python_version >= "3.8" and python_version < "4.0" and implementation_name == "pypy" pyarrow==10.0.1 ; python_version >= "3.8" and python_version < "4.0" -pycodestyle==2.10.0 ; python_full_version >= "3.8.1" and python_version < "4.0" -pycodestyle==2.9.1 ; python_version >= "3.8" and python_full_version < "3.8.1" pycparser==2.21 ; python_version >= "3.8" and python_version < "4.0" and implementation_name == "pypy" -pyflakes==2.5.0 ; python_version >= "3.8" and python_full_version < "3.8.1" -pyflakes==3.0.1 ; python_full_version >= "3.8.1" and python_version < "4.0" pygments==2.13.0 ; python_version >= "3.8" and python_version < "4.0" pymdown-extensions==9.9 ; python_version >= "3.8" and python_version < "4.0" pyparsing==3.0.9 ; python_version >= "3.8" and python_version < "4.0" @@ -123,13 +114,13 @@ python-dateutil==2.8.2 ; python_version >= "3.8" and python_version < "4.0" pytkdocs==0.16.1 ; python_version >= "3.8" and python_version < "4.0" pytkdocs[numpy-style]==0.16.1 ; python_version >= "3.8" and python_version < "4.0" pytz==2022.7 ; python_version >= "3.8" and python_version < "4.0" -pyupgrade==3.3.1 ; python_version >= "3.8" and python_version < "4.0" pywin32==305 ; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.8" and python_version < "4.0" pyyaml-env-tag==0.1 ; python_version >= "3.8" and python_version < "4.0" pyyaml==6.0 ; python_version >= "3.8" and python_version < "4.0" pyzmq==24.0.1 ; python_version >= "3.8" and python_version < "4.0" requests==2.28.1 ; python_version >= "3.8" and python_version < "4" rich==12.6.0 ; python_version >= "3.8" and python_version < "4.0" +ruff==0.0.189 ; python_version >= "3.8" and python_version < "4.0" six==1.16.0 ; python_version >= "3.8" and python_version < "4.0" smmap==5.0.0 ; python_version >= "3.8" and python_version < "4.0" soupsieve==2.3.2.post1 ; python_version >= "3.8" and python_version < "4" @@ -139,7 +130,6 @@ stack-data==0.6.2 ; python_version >= "3.8" and python_version < "4.0" tabulate==0.9.0 ; python_version >= "3.8" and python_version < "4.0" termcolor==2.1.1 ; python_version >= "3.8" and python_version < "4.0" tinycss2==1.2.1 ; python_version >= "3.8" and python_version < "4" -tokenize-rt==5.0.0 ; python_version >= "3.8" and python_version < "4.0" toml==0.10.2 ; python_version >= "3.8" and python_version < "4.0" tomli==2.0.1 ; python_version >= "3.8" and python_version < "4.0" tomlkit==0.11.6 ; python_version >= "3.8" and python_version < "4.0" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 9ff222cd21cc..000000000000 --- a/setup.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[flake8] -ignore = D202,D203,W503,E203,E501 -max-line-length = 88 -exclude = - ibis/tests/*/snapshots/*