From b3e750c1c12213c93106d0308c463f15f7a77b7b Mon Sep 17 00:00:00 2001 From: Aaron Miller Date: Tue, 17 Dec 2024 21:20:16 -0800 Subject: [PATCH] Delete pylint Move everything to ruff Topic: rm-pylint --- Makefile | 12 +- dev_requirements.txt | 25 +- docs/conf.py | 2 +- gen/python/sym/atan_camera_cal.py | 4 +- gen/python/sym/double_sphere_camera_cal.py | 4 +- gen/python/sym/equirectangular_camera_cal.py | 4 +- gen/python/sym/linear_camera_cal.py | 4 +- .../sym/ops/atan_camera_cal/camera_ops.py | 4 +- .../sym/ops/atan_camera_cal/group_ops.py | 4 +- .../sym/ops/atan_camera_cal/lie_group_ops.py | 4 +- .../double_sphere_camera_cal/camera_ops.py | 4 +- .../ops/double_sphere_camera_cal/group_ops.py | 4 +- .../double_sphere_camera_cal/lie_group_ops.py | 4 +- .../equirectangular_camera_cal/camera_ops.py | 4 +- .../equirectangular_camera_cal/group_ops.py | 4 +- .../lie_group_ops.py | 4 +- .../sym/ops/linear_camera_cal/camera_ops.py | 4 +- .../sym/ops/linear_camera_cal/group_ops.py | 4 +- .../ops/linear_camera_cal/lie_group_ops.py | 4 +- .../ops/orthographic_camera_cal/camera_ops.py | 4 +- .../ops/orthographic_camera_cal/group_ops.py | 4 +- .../orthographic_camera_cal/lie_group_ops.py | 4 +- .../ops/polynomial_camera_cal/camera_ops.py | 4 +- .../ops/polynomial_camera_cal/group_ops.py | 4 +- .../polynomial_camera_cal/lie_group_ops.py | 4 +- gen/python/sym/ops/pose2/group_ops.py | 4 +- gen/python/sym/ops/pose2/lie_group_ops.py | 4 +- gen/python/sym/ops/pose3/group_ops.py | 4 +- gen/python/sym/ops/pose3/lie_group_ops.py | 4 +- gen/python/sym/ops/rot2/group_ops.py | 4 +- gen/python/sym/ops/rot2/lie_group_ops.py | 4 +- gen/python/sym/ops/rot3/group_ops.py | 4 +- gen/python/sym/ops/rot3/lie_group_ops.py | 4 +- .../ops/spherical_camera_cal/camera_ops.py | 4 +- .../sym/ops/spherical_camera_cal/group_ops.py | 4 +- .../ops/spherical_camera_cal/lie_group_ops.py | 4 +- gen/python/sym/ops/unit3/group_ops.py | 4 +- gen/python/sym/ops/unit3/lie_group_ops.py | 4 +- gen/python/sym/orthographic_camera_cal.py | 4 +- gen/python/sym/polynomial_camera_cal.py | 6 +- gen/python/sym/pose2.py | 7 +- gen/python/sym/pose3.py | 7 +- gen/python/sym/rot2.py | 7 +- gen/python/sym/rot3.py | 7 +- gen/python/sym/spherical_camera_cal.py | 6 +- gen/python/sym/unit3.py | 5 +- notebooks/n-pendulum-control.ipynb | 2 - notebooks/tangent_D_storage.ipynb | 1 - notebooks/tutorials/epsilon_tutorial.ipynb | 217 +++---- pylintrc | 608 ------------------ pyproject.toml | 56 +- setup.py | 16 +- symforce/__init__.py | 8 +- symforce/_sympy_count_ops.py | 11 +- ...enerate_matrix_multiplication_benchmark.py | 16 +- .../notebooks/jax_inverse_compose.ipynb | 1 - .../benchmarks/notebooks/jax_matmul.ipynb | 1 - .../notebooks/jax_robot_localization.ipynb | 1 - .../benchmarks/notebooks/matmul_plots.ipynb | 10 +- symforce/benchmarks/run_benchmarks.py | 4 +- symforce/cam/polynomial_camera_cal.py | 17 +- symforce/cam/spherical_camera_cal.py | 15 +- symforce/cc_sym.py | 8 +- .../codegen/backends/cpp/cpp_code_printer.py | 11 +- symforce/codegen/backends/cpp/cpp_config.py | 3 +- .../backends/python/python_code_printer.py | 3 +- .../codegen/backends/python/python_config.py | 9 +- .../cam_package/ops/CLASS/camera_ops.py.jinja | 4 +- .../templates/function/FUNCTION.py.jinja | 6 +- .../templates/geo_package/CLASS.py.jinja | 5 +- .../templates/ops/CLASS/group_ops.py.jinja | 4 +- .../ops/CLASS/lie_group_ops.py.jinja | 4 +- .../tests/cam_package_python_test.py.jinja | 23 +- .../tests/geo_package_python_test.py.jinja | 15 +- .../backends/python/templates/util/util.jinja | 4 +- .../backends/pytorch/pytorch_code_printer.py | 18 +- .../backends/pytorch/pytorch_config.py | 9 +- .../templates/function/FUNCTION.py.jinja | 8 +- symforce/codegen/cam_package_codegen.py | 2 +- symforce/codegen/codegen_util.py | 4 +- symforce/codegen/format_util.py | 2 +- symforce/codegen/geo_factors_codegen.py | 4 +- symforce/codegen/geo_package_codegen.py | 2 +- symforce/codegen/slam_factors_codegen.py | 2 +- symforce/codegen/template_util.py | 21 +- symforce/codegen/types_package_codegen.py | 2 +- symforce/geo/__init__.py | 2 +- symforce/geo/complex.py | 4 +- symforce/geo/dual_quaternion.py | 4 +- symforce/geo/matrix.py | 26 +- symforce/geo/quaternion.py | 4 +- symforce/internal/symbolic.py | 36 +- symforce/ops/__init__.py | 2 +- symforce/ops/impl/nonetype_lie_group_ops.py | 2 +- symforce/opt/factor.py | 4 +- symforce/opt/optimizer.py | 5 +- symforce/python_util.py | 8 +- symforce/slam/imu_preintegration/generate.py | 2 +- .../imu_preintegration/manifold_symbolic.py | 4 +- symforce/symbolic.py | 4 +- .../unary_binary_expression_gen.py | 15 +- symforce/test_util/stubs_util.py | 2 +- symforce/test_util/test_case.py | 2 +- symforce/test_util/test_case_mixin.py | 7 +- symforce/type_helpers.py | 2 +- symforce/typing.py | 6 +- symforce/values/values.py | 4 +- test/cam_package_python_test.py | 119 +--- test/cam_spherical_test.py | 4 +- test/geo_matrix_test.py | 4 +- test/geo_package_python_test.py | 60 +- test/geo_rot3_test.py | 2 +- test/geo_unit3_test.py | 3 +- test/symforce_cc_sym_stubs_codegen_test.py | 2 +- test/symforce_cc_sym_test.py | 14 +- test/symforce_codegen_test.py | 6 +- test/symforce_from_rotation_matrix_test.py | 2 +- .../symengine/az_el_from_point.py | 6 +- .../codegen_dataclass_in_values_test.py | 6 +- .../codegen_python_test/python_function.py | 6 +- .../symforce/buffer_test/buffer_func.py | 6 +- .../symengine/numba_test_func.py | 8 +- .../backend_test_function.py | 8 +- .../pytorch_func.py | 8 +- .../sympy/az_el_from_point.py | 6 +- .../codegen_dataclass_in_values_test.py | 6 +- .../codegen_python_test/python_function.py | 6 +- .../symforce/buffer_test/buffer_func.py | 6 +- .../sympy/numba_test_func.py | 8 +- .../backend_test_function.py | 8 +- .../pytorch_func.py | 8 +- test/symforce_optimizer_test.cc | 1 - test/symforce_py_optimizer_test.py | 6 +- test/symforce_sympy_overrides_test.py | 4 +- test/symforce_type_helpers_test.py | 14 +- ...rce_values_generated_key_selection_test.py | 4 +- .../templates/python_init.py.template | 15 +- 137 files changed, 604 insertions(+), 1282 deletions(-) delete mode 100644 pylintrc diff --git a/Makefile b/Makefile index 5451592a1..fdbe84d8c 100644 --- a/Makefile +++ b/Makefile @@ -53,21 +53,19 @@ check_types: --exclude "symforce/examples/.*/gen/python2\.7/lcmtypes" \ --exclude third_party -# Run pylint on the symforce package, and tests -# TODO(aaron): Also run on other python code in symforce. Generated code will require a different -# config since it is py6 and contains a lot of duplicate code -pylint: - $(PYTHON) -m pylint symforce test/*.py +# Run ruff check +ruff_check: + ruff check # Lint check for formatting and type hints # This needs pass before any merge. -lint: check_types check_format pylint +lint: check_types check_format ruff_check # Clean all artifacts clean: docs_clean coverage_clean rm -rf $(BUILD_DIR) -.PHONY: all reqs format check_format check_types pylint lint clean +.PHONY: all reqs format check_format check_types ruff_check lint clean # ----------------------------------------------------------------------------- # Tests diff --git a/dev_requirements.txt b/dev_requirements.txt index 7bff27b38..6a11a1a1f 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -15,8 +15,6 @@ argh==0.31.2 # via # skymarshal # symforce (setup.py) -astroid==2.15.8 - # via pylint asttokens==2.4.1 # via stack-data attrs==23.2.0 @@ -63,8 +61,6 @@ decorator==5.1.1 # via ipython defusedxml==0.7.1 # via nbconvert -dill==0.3.8 - # via pylint docutils==0.20.1 # via # breathe @@ -103,8 +99,6 @@ ipython==8.12.3 # via ipykernel ipython-genutils==0.2.0 # via symforce (setup.py) -isort==5.13.2 - # via pylint jedi==0.19.1 # via ipython jinja2==3.1.4 @@ -134,8 +128,6 @@ jupyterlab-pygments==0.3.0 # via nbconvert kiwisolver==1.4.5 # via matplotlib -lazy-object-proxy==1.10.0 - # via astroid llvmlite==0.41.1 # via numba markdown-it-py==3.0.0 @@ -152,8 +144,6 @@ matplotlib-inline==0.1.7 # via # ipykernel # ipython -mccabe==0.7.0 - # via pylint mdit-py-plugins==0.4.1 # via myst-parser mdurl==0.1.2 @@ -221,9 +211,7 @@ pip-tools==7.4.1 pkgutil-resolve-name==1.3.10 # via jsonschema platformdirs==4.2.2 - # via - # jupyter-core - # pylint + # via jupyter-core plotly==5.22.0 # via symforce (setup.py) ply==3.11 @@ -244,8 +232,6 @@ pygments==2.18.0 # ipython # nbconvert # sphinx -pylint==2.17.7 - # via symforce (setup.py) pyparsing==3.1.2 # via matplotlib pyproject-hooks==1.1.0 @@ -277,7 +263,7 @@ rpds-py==0.18.1 # via # jsonschema # referencing -ruff==0.5.4 +ruff==0.7.1 # via symforce (setup.py) scipy==1.10.1 # via symforce (setup.py) @@ -335,9 +321,6 @@ tomli==2.0.1 # build # mypy # pip-tools - # pylint -tomlkit==0.12.5 - # via pylint tornado==6.4 # via # ipykernel @@ -364,10 +347,8 @@ types-setuptools==69.5.0.20240513 # via symforce (setup.py) typing-extensions==4.11.0 # via - # astroid # ipython # mypy - # pylint tzdata==2024.1 # via pandas urllib3==2.2.1 @@ -384,8 +365,6 @@ wheel==0.43.0 # via # pip-tools # symforce (setup.py) -wrapt==1.16.0 - # via astroid zipp==3.18.1 # via # importlib-metadata diff --git a/docs/conf.py b/docs/conf.py index d76affaf3..e460dcbdc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -27,7 +27,7 @@ # -- Project information ----------------------------------------------------- project = "symforce" -copyright = "2022, Skydio, Inc" +copyright = "2022, Skydio, Inc" # noqa: A001 author = "Skydio" # The short X.Y version diff --git a/gen/python/sym/atan_camera_cal.py b/gen/python/sym/atan_camera_cal.py index 90f8a915a..59815ac94 100644 --- a/gen/python/sym/atan_camera_cal.py +++ b/gen/python/sym/atan_camera_cal.py @@ -35,7 +35,7 @@ def __init__(self, focal_length, principal_point, omega): # type: (T.Union[T.Sequence[float], numpy.ndarray], T.Union[T.Sequence[float], numpy.ndarray], float) -> None self.data = [] if isinstance(focal_length, numpy.ndarray): - if focal_length.shape in [(2, 1), (1, 2)]: + if focal_length.shape in {(2, 1), (1, 2)}: focal_length = focal_length.flatten() elif focal_length.shape != (2,): raise IndexError( @@ -50,7 +50,7 @@ def __init__(self, focal_length, principal_point, omega): ) ) if isinstance(principal_point, numpy.ndarray): - if principal_point.shape in [(2, 1), (1, 2)]: + if principal_point.shape in {(2, 1), (1, 2)}: principal_point = principal_point.flatten() elif principal_point.shape != (2,): raise IndexError( diff --git a/gen/python/sym/double_sphere_camera_cal.py b/gen/python/sym/double_sphere_camera_cal.py index 066563bf4..ee02b8fd3 100644 --- a/gen/python/sym/double_sphere_camera_cal.py +++ b/gen/python/sym/double_sphere_camera_cal.py @@ -47,7 +47,7 @@ def __init__(self, focal_length, principal_point, xi, alpha): # type: (T.Union[T.Sequence[float], numpy.ndarray], T.Union[T.Sequence[float], numpy.ndarray], float, float) -> None self.data = [] if isinstance(focal_length, numpy.ndarray): - if focal_length.shape in [(2, 1), (1, 2)]: + if focal_length.shape in {(2, 1), (1, 2)}: focal_length = focal_length.flatten() elif focal_length.shape != (2,): raise IndexError( @@ -62,7 +62,7 @@ def __init__(self, focal_length, principal_point, xi, alpha): ) ) if isinstance(principal_point, numpy.ndarray): - if principal_point.shape in [(2, 1), (1, 2)]: + if principal_point.shape in {(2, 1), (1, 2)}: principal_point = principal_point.flatten() elif principal_point.shape != (2,): raise IndexError( diff --git a/gen/python/sym/equirectangular_camera_cal.py b/gen/python/sym/equirectangular_camera_cal.py index 412086d2f..2cd22f16f 100644 --- a/gen/python/sym/equirectangular_camera_cal.py +++ b/gen/python/sym/equirectangular_camera_cal.py @@ -31,7 +31,7 @@ def __init__(self, focal_length, principal_point): # type: (T.Union[T.Sequence[float], numpy.ndarray], T.Union[T.Sequence[float], numpy.ndarray]) -> None self.data = [] if isinstance(focal_length, numpy.ndarray): - if focal_length.shape in [(2, 1), (1, 2)]: + if focal_length.shape in {(2, 1), (1, 2)}: focal_length = focal_length.flatten() elif focal_length.shape != (2,): raise IndexError( @@ -46,7 +46,7 @@ def __init__(self, focal_length, principal_point): ) ) if isinstance(principal_point, numpy.ndarray): - if principal_point.shape in [(2, 1), (1, 2)]: + if principal_point.shape in {(2, 1), (1, 2)}: principal_point = principal_point.flatten() elif principal_point.shape != (2,): raise IndexError( diff --git a/gen/python/sym/linear_camera_cal.py b/gen/python/sym/linear_camera_cal.py index 1cefee792..ddf162df6 100644 --- a/gen/python/sym/linear_camera_cal.py +++ b/gen/python/sym/linear_camera_cal.py @@ -31,7 +31,7 @@ def __init__(self, focal_length, principal_point): # type: (T.Union[T.Sequence[float], numpy.ndarray], T.Union[T.Sequence[float], numpy.ndarray]) -> None self.data = [] if isinstance(focal_length, numpy.ndarray): - if focal_length.shape in [(2, 1), (1, 2)]: + if focal_length.shape in {(2, 1), (1, 2)}: focal_length = focal_length.flatten() elif focal_length.shape != (2,): raise IndexError( @@ -46,7 +46,7 @@ def __init__(self, focal_length, principal_point): ) ) if isinstance(principal_point, numpy.ndarray): - if principal_point.shape in [(2, 1), (1, 2)]: + if principal_point.shape in {(2, 1), (1, 2)}: principal_point = principal_point.flatten() elif principal_point.shape != (2,): raise IndexError( diff --git a/gen/python/sym/ops/atan_camera_cal/camera_ops.py b/gen/python/sym/ops/atan_camera_cal/camera_ops.py index f891e7fd5..8f56a5afa 100644 --- a/gen/python/sym/ops/atan_camera_cal/camera_ops.py +++ b/gen/python/sym/ops/atan_camera_cal/camera_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class CameraOps(object): diff --git a/gen/python/sym/ops/atan_camera_cal/group_ops.py b/gen/python/sym/ops/atan_camera_cal/group_ops.py index 6ff040f43..88fd12615 100644 --- a/gen/python/sym/ops/atan_camera_cal/group_ops.py +++ b/gen/python/sym/ops/atan_camera_cal/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/atan_camera_cal/lie_group_ops.py b/gen/python/sym/ops/atan_camera_cal/lie_group_ops.py index c475d50ab..159b170ba 100644 --- a/gen/python/sym/ops/atan_camera_cal/lie_group_ops.py +++ b/gen/python/sym/ops/atan_camera_cal/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/ops/double_sphere_camera_cal/camera_ops.py b/gen/python/sym/ops/double_sphere_camera_cal/camera_ops.py index 24fe28177..d2edfe330 100644 --- a/gen/python/sym/ops/double_sphere_camera_cal/camera_ops.py +++ b/gen/python/sym/ops/double_sphere_camera_cal/camera_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class CameraOps(object): diff --git a/gen/python/sym/ops/double_sphere_camera_cal/group_ops.py b/gen/python/sym/ops/double_sphere_camera_cal/group_ops.py index f2deeca36..e82bd9428 100644 --- a/gen/python/sym/ops/double_sphere_camera_cal/group_ops.py +++ b/gen/python/sym/ops/double_sphere_camera_cal/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/double_sphere_camera_cal/lie_group_ops.py b/gen/python/sym/ops/double_sphere_camera_cal/lie_group_ops.py index 9927cf78e..f12af964d 100644 --- a/gen/python/sym/ops/double_sphere_camera_cal/lie_group_ops.py +++ b/gen/python/sym/ops/double_sphere_camera_cal/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/ops/equirectangular_camera_cal/camera_ops.py b/gen/python/sym/ops/equirectangular_camera_cal/camera_ops.py index c8809dc8e..31ba8e163 100644 --- a/gen/python/sym/ops/equirectangular_camera_cal/camera_ops.py +++ b/gen/python/sym/ops/equirectangular_camera_cal/camera_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class CameraOps(object): diff --git a/gen/python/sym/ops/equirectangular_camera_cal/group_ops.py b/gen/python/sym/ops/equirectangular_camera_cal/group_ops.py index edaa785e3..078f140eb 100644 --- a/gen/python/sym/ops/equirectangular_camera_cal/group_ops.py +++ b/gen/python/sym/ops/equirectangular_camera_cal/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/equirectangular_camera_cal/lie_group_ops.py b/gen/python/sym/ops/equirectangular_camera_cal/lie_group_ops.py index 3093bd388..4f84d36a8 100644 --- a/gen/python/sym/ops/equirectangular_camera_cal/lie_group_ops.py +++ b/gen/python/sym/ops/equirectangular_camera_cal/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/ops/linear_camera_cal/camera_ops.py b/gen/python/sym/ops/linear_camera_cal/camera_ops.py index 883745594..d4d1f59c5 100644 --- a/gen/python/sym/ops/linear_camera_cal/camera_ops.py +++ b/gen/python/sym/ops/linear_camera_cal/camera_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class CameraOps(object): diff --git a/gen/python/sym/ops/linear_camera_cal/group_ops.py b/gen/python/sym/ops/linear_camera_cal/group_ops.py index fe6f16294..f6f7b8857 100644 --- a/gen/python/sym/ops/linear_camera_cal/group_ops.py +++ b/gen/python/sym/ops/linear_camera_cal/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/linear_camera_cal/lie_group_ops.py b/gen/python/sym/ops/linear_camera_cal/lie_group_ops.py index e1fb8f94e..ecccac3bb 100644 --- a/gen/python/sym/ops/linear_camera_cal/lie_group_ops.py +++ b/gen/python/sym/ops/linear_camera_cal/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/ops/orthographic_camera_cal/camera_ops.py b/gen/python/sym/ops/orthographic_camera_cal/camera_ops.py index ebc1d74c0..31f308787 100644 --- a/gen/python/sym/ops/orthographic_camera_cal/camera_ops.py +++ b/gen/python/sym/ops/orthographic_camera_cal/camera_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class CameraOps(object): diff --git a/gen/python/sym/ops/orthographic_camera_cal/group_ops.py b/gen/python/sym/ops/orthographic_camera_cal/group_ops.py index b4f96d7a1..1940ece18 100644 --- a/gen/python/sym/ops/orthographic_camera_cal/group_ops.py +++ b/gen/python/sym/ops/orthographic_camera_cal/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/orthographic_camera_cal/lie_group_ops.py b/gen/python/sym/ops/orthographic_camera_cal/lie_group_ops.py index aa6e36016..ade6075d6 100644 --- a/gen/python/sym/ops/orthographic_camera_cal/lie_group_ops.py +++ b/gen/python/sym/ops/orthographic_camera_cal/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/ops/polynomial_camera_cal/camera_ops.py b/gen/python/sym/ops/polynomial_camera_cal/camera_ops.py index 01e8d120a..9cf9feb1c 100644 --- a/gen/python/sym/ops/polynomial_camera_cal/camera_ops.py +++ b/gen/python/sym/ops/polynomial_camera_cal/camera_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class CameraOps(object): diff --git a/gen/python/sym/ops/polynomial_camera_cal/group_ops.py b/gen/python/sym/ops/polynomial_camera_cal/group_ops.py index a1f711a07..9bb3c4f90 100644 --- a/gen/python/sym/ops/polynomial_camera_cal/group_ops.py +++ b/gen/python/sym/ops/polynomial_camera_cal/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/polynomial_camera_cal/lie_group_ops.py b/gen/python/sym/ops/polynomial_camera_cal/lie_group_ops.py index 534b5b7d9..64d60f674 100644 --- a/gen/python/sym/ops/polynomial_camera_cal/lie_group_ops.py +++ b/gen/python/sym/ops/polynomial_camera_cal/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/ops/pose2/group_ops.py b/gen/python/sym/ops/pose2/group_ops.py index 978b5740e..ed118b5bf 100644 --- a/gen/python/sym/ops/pose2/group_ops.py +++ b/gen/python/sym/ops/pose2/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/pose2/lie_group_ops.py b/gen/python/sym/ops/pose2/lie_group_ops.py index dbc14def9..2e34657b4 100644 --- a/gen/python/sym/ops/pose2/lie_group_ops.py +++ b/gen/python/sym/ops/pose2/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/ops/pose3/group_ops.py b/gen/python/sym/ops/pose3/group_ops.py index 60cd4465d..266e4378e 100644 --- a/gen/python/sym/ops/pose3/group_ops.py +++ b/gen/python/sym/ops/pose3/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/pose3/lie_group_ops.py b/gen/python/sym/ops/pose3/lie_group_ops.py index dc88ceed0..6456b0070 100644 --- a/gen/python/sym/ops/pose3/lie_group_ops.py +++ b/gen/python/sym/ops/pose3/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/ops/rot2/group_ops.py b/gen/python/sym/ops/rot2/group_ops.py index fd7a68df1..646a77411 100644 --- a/gen/python/sym/ops/rot2/group_ops.py +++ b/gen/python/sym/ops/rot2/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/rot2/lie_group_ops.py b/gen/python/sym/ops/rot2/lie_group_ops.py index 76c843a8c..0860c7456 100644 --- a/gen/python/sym/ops/rot2/lie_group_ops.py +++ b/gen/python/sym/ops/rot2/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/ops/rot3/group_ops.py b/gen/python/sym/ops/rot3/group_ops.py index e72b4cb43..7cce2241c 100644 --- a/gen/python/sym/ops/rot3/group_ops.py +++ b/gen/python/sym/ops/rot3/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/rot3/lie_group_ops.py b/gen/python/sym/ops/rot3/lie_group_ops.py index 2b0102388..339c356d0 100644 --- a/gen/python/sym/ops/rot3/lie_group_ops.py +++ b/gen/python/sym/ops/rot3/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/ops/spherical_camera_cal/camera_ops.py b/gen/python/sym/ops/spherical_camera_cal/camera_ops.py index ffbf3dd79..e7ba0f885 100644 --- a/gen/python/sym/ops/spherical_camera_cal/camera_ops.py +++ b/gen/python/sym/ops/spherical_camera_cal/camera_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class CameraOps(object): diff --git a/gen/python/sym/ops/spherical_camera_cal/group_ops.py b/gen/python/sym/ops/spherical_camera_cal/group_ops.py index cab74aa77..a94ed48eb 100644 --- a/gen/python/sym/ops/spherical_camera_cal/group_ops.py +++ b/gen/python/sym/ops/spherical_camera_cal/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/spherical_camera_cal/lie_group_ops.py b/gen/python/sym/ops/spherical_camera_cal/lie_group_ops.py index 923a74455..dad90a54d 100644 --- a/gen/python/sym/ops/spherical_camera_cal/lie_group_ops.py +++ b/gen/python/sym/ops/spherical_camera_cal/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/ops/unit3/group_ops.py b/gen/python/sym/ops/unit3/group_ops.py index 56465b992..0aa8ad1f9 100644 --- a/gen/python/sym/ops/unit3/group_ops.py +++ b/gen/python/sym/ops/unit3/group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/gen/python/sym/ops/unit3/lie_group_ops.py b/gen/python/sym/ops/unit3/lie_group_ops.py index a7ded49c3..1b785ccde 100644 --- a/gen/python/sym/ops/unit3/lie_group_ops.py +++ b/gen/python/sym/ops/unit3/lie_group_ops.py @@ -4,12 +4,14 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/gen/python/sym/orthographic_camera_cal.py b/gen/python/sym/orthographic_camera_cal.py index f3a7cd5ad..da33b4b6a 100644 --- a/gen/python/sym/orthographic_camera_cal.py +++ b/gen/python/sym/orthographic_camera_cal.py @@ -39,7 +39,7 @@ def __init__(self, focal_length, principal_point): # type: (T.Union[T.Sequence[float], numpy.ndarray], T.Union[T.Sequence[float], numpy.ndarray]) -> None self.data = [] if isinstance(focal_length, numpy.ndarray): - if focal_length.shape in [(2, 1), (1, 2)]: + if focal_length.shape in {(2, 1), (1, 2)}: focal_length = focal_length.flatten() elif focal_length.shape != (2,): raise IndexError( @@ -54,7 +54,7 @@ def __init__(self, focal_length, principal_point): ) ) if isinstance(principal_point, numpy.ndarray): - if principal_point.shape in [(2, 1), (1, 2)]: + if principal_point.shape in {(2, 1), (1, 2)}: principal_point = principal_point.flatten() elif principal_point.shape != (2,): raise IndexError( diff --git a/gen/python/sym/polynomial_camera_cal.py b/gen/python/sym/polynomial_camera_cal.py index d8de7ea43..56a343233 100644 --- a/gen/python/sym/polynomial_camera_cal.py +++ b/gen/python/sym/polynomial_camera_cal.py @@ -42,7 +42,7 @@ def __init__( # type: (T.Union[T.Sequence[float], numpy.ndarray], T.Union[T.Sequence[float], numpy.ndarray], float, T.Union[T.Sequence[float], numpy.ndarray]) -> None self.data = [] if isinstance(focal_length, numpy.ndarray): - if focal_length.shape in [(2, 1), (1, 2)]: + if focal_length.shape in {(2, 1), (1, 2)}: focal_length = focal_length.flatten() elif focal_length.shape != (2,): raise IndexError( @@ -57,7 +57,7 @@ def __init__( ) ) if isinstance(principal_point, numpy.ndarray): - if principal_point.shape in [(2, 1), (1, 2)]: + if principal_point.shape in {(2, 1), (1, 2)}: principal_point = principal_point.flatten() elif principal_point.shape != (2,): raise IndexError( @@ -72,7 +72,7 @@ def __init__( ) ) if isinstance(distortion_coeffs, numpy.ndarray): - if distortion_coeffs.shape in [(3, 1), (1, 3)]: + if distortion_coeffs.shape in {(3, 1), (1, 3)}: distortion_coeffs = distortion_coeffs.flatten() elif distortion_coeffs.shape != (3,): raise IndexError( diff --git a/gen/python/sym/pose2.py b/gen/python/sym/pose2.py index f30928acb..c043145d1 100644 --- a/gen/python/sym/pose2.py +++ b/gen/python/sym/pose2.py @@ -4,6 +4,9 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- + +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import random import typing as T @@ -60,7 +63,7 @@ def __init__(self, R=None, t=None): if t is None: t = [0.0, 0.0] if isinstance(t, numpy.ndarray): - if t.shape in [(2, 1), (1, 2)]: + if t.shape in {(2, 1), (1, 2)}: t = t.flatten() elif t.shape != (2,): raise IndexError( @@ -351,6 +354,6 @@ def __mul__(self, other): if isinstance(other, Pose2): return self.compose(other) elif isinstance(other, numpy.ndarray) and hasattr(self, "compose_with_point"): - return getattr(self, "compose_with_point")(other).reshape(other.shape) + return self.compose_with_point(other).reshape(other.shape) else: raise NotImplementedError("Cannot compose {} with {}.".format(type(self), type(other))) diff --git a/gen/python/sym/pose3.py b/gen/python/sym/pose3.py index fa2e4f3da..aca970242 100644 --- a/gen/python/sym/pose3.py +++ b/gen/python/sym/pose3.py @@ -4,6 +4,9 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- + +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import random import typing as T @@ -60,7 +63,7 @@ def __init__(self, R=None, t=None): if t is None: t = [0.0, 0.0, 0.0] if isinstance(t, numpy.ndarray): - if t.shape in [(3, 1), (1, 3)]: + if t.shape in {(3, 1), (1, 3)}: t = t.flatten() elif t.shape != (3,): raise IndexError( @@ -428,6 +431,6 @@ def __mul__(self, other): if isinstance(other, Pose3): return self.compose(other) elif isinstance(other, numpy.ndarray) and hasattr(self, "compose_with_point"): - return getattr(self, "compose_with_point")(other).reshape(other.shape) + return self.compose_with_point(other).reshape(other.shape) else: raise NotImplementedError("Cannot compose {} with {}.".format(type(self), type(other))) diff --git a/gen/python/sym/rot2.py b/gen/python/sym/rot2.py index 319fc4e45..44ee8538b 100644 --- a/gen/python/sym/rot2.py +++ b/gen/python/sym/rot2.py @@ -4,6 +4,9 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- + +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import random import typing as T @@ -38,7 +41,7 @@ def __init__(self, z=None): self.data = ops.GroupOps.identity().data # type: T.List[float] else: if isinstance(z, numpy.ndarray): - if z.shape in [(2, 1), (1, 2)]: + if z.shape in {(2, 1), (1, 2)}: z = z.flatten() elif z.shape != (2,): raise IndexError( @@ -294,6 +297,6 @@ def __mul__(self, other): if isinstance(other, Rot2): return self.compose(other) elif isinstance(other, numpy.ndarray) and hasattr(self, "compose_with_point"): - return getattr(self, "compose_with_point")(other).reshape(other.shape) + return self.compose_with_point(other).reshape(other.shape) else: raise NotImplementedError("Cannot compose {} with {}.".format(type(self), type(other))) diff --git a/gen/python/sym/rot3.py b/gen/python/sym/rot3.py index f8fa04f2c..fcccda4a7 100644 --- a/gen/python/sym/rot3.py +++ b/gen/python/sym/rot3.py @@ -4,6 +4,9 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- + +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import random import typing as T @@ -38,7 +41,7 @@ def __init__(self, q=None): self.data = ops.GroupOps.identity().data # type: T.List[float] else: if isinstance(q, numpy.ndarray): - if q.shape in [(4, 1), (1, 4)]: + if q.shape in {(4, 1), (1, 4)}: q = q.flatten() elif q.shape != (4,): raise IndexError( @@ -568,6 +571,6 @@ def __mul__(self, other): if isinstance(other, Rot3): return self.compose(other) elif isinstance(other, numpy.ndarray) and hasattr(self, "compose_with_point"): - return getattr(self, "compose_with_point")(other).reshape(other.shape) + return self.compose_with_point(other).reshape(other.shape) else: raise NotImplementedError("Cannot compose {} with {}.".format(type(self), type(other))) diff --git a/gen/python/sym/spherical_camera_cal.py b/gen/python/sym/spherical_camera_cal.py index fdf36e14e..89636431f 100644 --- a/gen/python/sym/spherical_camera_cal.py +++ b/gen/python/sym/spherical_camera_cal.py @@ -62,7 +62,7 @@ def __init__(self, focal_length, principal_point, critical_theta, distortion_coe # type: (T.Union[T.Sequence[float], numpy.ndarray], T.Union[T.Sequence[float], numpy.ndarray], float, T.Union[T.Sequence[float], numpy.ndarray]) -> None self.data = [] if isinstance(focal_length, numpy.ndarray): - if focal_length.shape in [(2, 1), (1, 2)]: + if focal_length.shape in {(2, 1), (1, 2)}: focal_length = focal_length.flatten() elif focal_length.shape != (2,): raise IndexError( @@ -77,7 +77,7 @@ def __init__(self, focal_length, principal_point, critical_theta, distortion_coe ) ) if isinstance(principal_point, numpy.ndarray): - if principal_point.shape in [(2, 1), (1, 2)]: + if principal_point.shape in {(2, 1), (1, 2)}: principal_point = principal_point.flatten() elif principal_point.shape != (2,): raise IndexError( @@ -92,7 +92,7 @@ def __init__(self, focal_length, principal_point, critical_theta, distortion_coe ) ) if isinstance(distortion_coeffs, numpy.ndarray): - if distortion_coeffs.shape in [(6, 1), (1, 6)]: + if distortion_coeffs.shape in {(6, 1), (1, 6)}: distortion_coeffs = distortion_coeffs.flatten() elif distortion_coeffs.shape != (6,): raise IndexError( diff --git a/gen/python/sym/unit3.py b/gen/python/sym/unit3.py index 10b048a3d..f92017549 100644 --- a/gen/python/sym/unit3.py +++ b/gen/python/sym/unit3.py @@ -4,6 +4,9 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- + +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import random import typing as T @@ -277,6 +280,6 @@ def __mul__(self, other): if isinstance(other, Unit3): return self.compose(other) elif isinstance(other, numpy.ndarray) and hasattr(self, "compose_with_point"): - return getattr(self, "compose_with_point")(other).reshape(other.shape) + return self.compose_with_point(other).reshape(other.shape) else: raise NotImplementedError("Cannot compose {} with {}.".format(type(self), type(other))) diff --git a/notebooks/n-pendulum-control.ipynb b/notebooks/n-pendulum-control.ipynb index e2a9a826a..a6e584b0e 100644 --- a/notebooks/n-pendulum-control.ipynb +++ b/notebooks/n-pendulum-control.ipynb @@ -50,7 +50,6 @@ "metadata": {}, "outputs": [], "source": [ - "import numpy as np\n", "import sympy as sm\n", "import sympy.physics.mechanics as me" ] @@ -762,7 +761,6 @@ "metadata": {}, "outputs": [], "source": [ - "from numpy.linalg import matrix_rank\n", "from scipy.linalg import solve_continuous_are" ] }, diff --git a/notebooks/tangent_D_storage.ipynb b/notebooks/tangent_D_storage.ipynb index adfbabafd..a9f4d25a8 100644 --- a/notebooks/tangent_D_storage.ipynb +++ b/notebooks/tangent_D_storage.ipynb @@ -13,7 +13,6 @@ "\n", "import symforce.symbolic as sf\n", "from symforce.ops import LieGroupOps\n", - "from symforce.ops import StorageOps\n", "\n", "epsilon = 1e-9" ] diff --git a/notebooks/tutorials/epsilon_tutorial.ipynb b/notebooks/tutorials/epsilon_tutorial.ipynb index d69304e63..bc5caaf6f 100644 --- a/notebooks/tutorials/epsilon_tutorial.ipynb +++ b/notebooks/tutorials/epsilon_tutorial.ipynb @@ -297,7 +297,8 @@ "outputs": [], "source": [ "# Original function fails, singular at x=0\n", - "assert is_epsilon_correct(lambda x, eps: sm.sin(x) / x) == False" + "correct = is_epsilon_correct(lambda x, eps: sm.sin(x) / x)\n", + "assert not correct" ] }, { @@ -307,7 +308,8 @@ "outputs": [], "source": [ "# Original broken attempt\n", - "assert is_epsilon_correct(lambda x, eps: sm.sin(x) / (eps + x)) == False" + "correct = is_epsilon_correct(lambda x, eps: sm.sin(x) / (eps + x))\n", + "assert not correct" ] }, { @@ -317,7 +319,8 @@ "outputs": [], "source": [ "# Additive on top/bottom works\n", - "assert is_epsilon_correct(lambda x, eps: (eps + sm.sin(x)) / (eps + x)) == True" + "correct = is_epsilon_correct(lambda x, eps: (eps + sm.sin(x)) / (eps + x))\n", + "assert correct" ] }, { @@ -327,7 +330,8 @@ "outputs": [], "source": [ "# Replacing all x with (x + eps) works\n", - "assert is_epsilon_correct(lambda x, eps: sm.sin(x + eps) / (x + eps)) == True" + "correct = is_epsilon_correct(lambda x, eps: sm.sin(x + eps) / (x + eps))\n", + "assert correct" ] }, { @@ -345,7 +349,8 @@ "outputs": [], "source": [ "# Original fails, singular at 0\n", - "assert is_epsilon_correct(lambda x, eps: (1 - sm.cos(x)) / x) == False" + "correct = is_epsilon_correct(lambda x, eps: (1 - sm.cos(x)) / x)\n", + "assert not correct" ] }, { @@ -356,7 +361,8 @@ "source": [ "# Value passes if we just replace the denominator, because this one is\n", "# ~ x**2 / x unlike the above which is ~ x / x\n", - "assert is_epsilon_correct(lambda x, eps: (1 - sm.cos(x)) / (x + eps)) == False" + "correct = is_epsilon_correct(lambda x, eps: (1 - sm.cos(x)) / (x + eps))\n", + "assert not correct" ] }, { @@ -366,7 +372,8 @@ "outputs": [], "source": [ "# Derivative also passes if we replace both\n", - "assert is_epsilon_correct(lambda x, eps: (1 - sm.cos(x + eps)) / (x + eps)) == True" + "correct = is_epsilon_correct(lambda x, eps: (1 - sm.cos(x + eps)) / (x + eps))\n", + "assert correct" ] }, { @@ -384,7 +391,8 @@ "outputs": [], "source": [ "# Original fails, singular at 0\n", - "assert is_epsilon_correct(lambda x, eps: x / sm.sqrt(x**2)) == False" + "correct = is_epsilon_correct(lambda x, eps: x / sm.sqrt(x**2))\n", + "assert not correct" ] }, { @@ -394,7 +402,8 @@ "outputs": [], "source": [ "# Broken fix #1\n", - "assert is_epsilon_correct(lambda x, eps: x / sm.sqrt(x**2 + eps**2)) == False" + "correct = is_epsilon_correct(lambda x, eps: x / sm.sqrt(x**2 + eps**2))\n", + "assert not correct" ] }, { @@ -404,12 +413,10 @@ "outputs": [], "source": [ "# Broken fix #2\n", - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: (x + eps) / sm.sqrt(x**2 + eps**2),\n", - " )\n", - " == False\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: (x + eps) / sm.sqrt(x**2 + eps**2),\n", + ")\n", + "assert not correct" ] }, { @@ -419,12 +426,10 @@ "outputs": [], "source": [ "# Broken fix #3, ugh\n", - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: (x + eps) / (eps + sm.sqrt(x**2 + eps**2)),\n", - " )\n", - " == False\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: (x + eps) / (eps + sm.sqrt(x**2 + eps**2)),\n", + ")\n", + "assert not correct" ] }, { @@ -434,12 +439,10 @@ "outputs": [], "source": [ "# Working if you again replace all x with x + eps\n", - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: (x + eps) / sm.sqrt((x + eps) ** 2),\n", - " )\n", - " == True\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: (x + eps) / sm.sqrt((x + eps) ** 2),\n", + ")\n", + "assert correct" ] }, { @@ -457,13 +460,11 @@ "outputs": [], "source": [ "# Original fails, singular at 1\n", - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: sm.acos(x) / sm.sqrt(1 - x**2),\n", - " singularity=1,\n", - " )\n", - " == False\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: sm.acos(x) / sm.sqrt(1 - x**2),\n", + " singularity=1,\n", + ")\n", + "assert not correct" ] }, { @@ -473,13 +474,11 @@ "outputs": [], "source": [ "# Working if you replace all x with x + eps\n", - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: sm.acos(x + eps) / sm.sqrt(1 - (x + eps) ** 2),\n", - " singularity=1,\n", - " )\n", - " == True\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: sm.acos(x + eps) / sm.sqrt(1 - (x + eps) ** 2),\n", + " singularity=1,\n", + ")\n", + "assert correct" ] }, { @@ -497,7 +496,8 @@ "outputs": [], "source": [ "# Original is singular\n", - "assert is_epsilon_correct(lambda x, eps: sm.atan2(0, x)) == False" + "correct = is_epsilon_correct(lambda x, eps: sm.atan2(0, x))\n", + "assert not correct" ] }, { @@ -507,7 +507,8 @@ "outputs": [], "source": [ "# This works\n", - "assert is_epsilon_correct(lambda x, eps: sm.atan2(0, x + eps)) == True" + "correct = is_epsilon_correct(lambda x, eps: sm.atan2(0, x + eps))\n", + "assert correct" ] }, { @@ -552,12 +553,10 @@ "outputs": [], "source": [ "# Test for sin(x) / x\n", - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: (sm.sin(x + eps * sign_no_zero(x))) / (x + eps * sign_no_zero(x))\n", - " )\n", - " == True\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: (sm.sin(x + eps * sign_no_zero(x))) / (x + eps * sign_no_zero(x))\n", + ")\n", + "assert correct" ] }, { @@ -567,12 +566,10 @@ "outputs": [], "source": [ "# Test for x / sqrt(x**2)\n", - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: (x + eps) / sm.sqrt((x + eps) ** 2),\n", - " )\n", - " == True\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: (x + eps) / sm.sqrt((x + eps) ** 2),\n", + ")\n", + "assert correct" ] }, { @@ -582,12 +579,10 @@ "outputs": [], "source": [ "# Test for atan2(0, x)\n", - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: sm.atan2(0, x + eps * sign_no_zero(x)),\n", - " )\n", - " == True\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: sm.atan2(0, x + eps * sign_no_zero(x)),\n", + ")\n", + "assert correct" ] }, { @@ -623,12 +618,10 @@ "outputs": [], "source": [ "# Check known example\n", - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: add_epsilon_sign(sm.sin(x) / x, x, eps),\n", - " )\n", - " == True\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: add_epsilon_sign(sm.sin(x) / x, x, eps),\n", + ")\n", + "assert correct" ] }, { @@ -638,16 +631,14 @@ "outputs": [], "source": [ "# Try some more complicated thing nobody wants to epsilon by hand\n", - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: add_epsilon_sign(\n", - " (x + sm.sin(x) ** 2) / (x * (1 - 1 / x)),\n", - " x,\n", - " eps,\n", - " )\n", + "correct = is_epsilon_correct(\n", + " lambda x, eps: add_epsilon_sign(\n", + " (x + sm.sin(x) ** 2) / (x * (1 - 1 / x)),\n", + " x,\n", + " eps,\n", " )\n", - " == True\n", - ")" + ")\n", + "assert correct" ] }, { @@ -675,18 +666,16 @@ "outputs": [], "source": [ "# Check known example\n", - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: add_epsilon_near_1_sign(\n", - " sm.cos(x) / sm.sqrt(1 - x**2),\n", - " x,\n", - " eps,\n", - " ),\n", - " singularity=1,\n", - " limit_direction=\"-\",\n", - " )\n", - " == True\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: add_epsilon_near_1_sign(\n", + " sm.cos(x) / sm.sqrt(1 - x**2),\n", + " x,\n", + " eps,\n", + " ),\n", + " singularity=1,\n", + " limit_direction=\"-\",\n", + ")\n", + "assert correct" ] }, { @@ -727,12 +716,10 @@ "metadata": {}, "outputs": [], "source": [ - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: add_epsilon_sign((sm.sin(x) + x**2) / x, x, eps),\n", - " )\n", - " == True\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: add_epsilon_sign((sm.sin(x) + x**2) / x, x, eps),\n", + ")\n", + "assert correct" ] }, { @@ -749,12 +736,10 @@ "metadata": {}, "outputs": [], "source": [ - "assert (\n", - " is_epsilon_correct(\n", - " lambda x, eps: add_epsilon_max((sm.sin(x) + x**2) / x, x, eps),\n", - " )\n", - " == False\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda x, eps: add_epsilon_max((sm.sin(x) + x**2) / x, x, eps),\n", + ")\n", + "assert not correct" ] }, { @@ -853,12 +838,10 @@ "metadata": {}, "outputs": [], "source": [ - "assert (\n", - " is_epsilon_correct(\n", - " lambda theta, eps: (0.5 * theta * sm.sin(theta)) / (1 - sm.cos(theta)),\n", - " )\n", - " == False\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda theta, eps: (0.5 * theta * sm.sin(theta)) / (1 - sm.cos(theta)),\n", + ")\n", + "assert not correct" ] }, { @@ -875,14 +858,12 @@ "metadata": {}, "outputs": [], "source": [ - "assert (\n", - " is_epsilon_correct(\n", - " lambda theta, eps: add_epsilon_sign(\n", - " (0.5 * theta * sm.sin(theta)) / (1 - sm.cos(theta)), theta, eps\n", - " )\n", + "correct = is_epsilon_correct(\n", + " lambda theta, eps: add_epsilon_sign(\n", + " (0.5 * theta * sm.sin(theta)) / (1 - sm.cos(theta)), theta, eps\n", " )\n", - " == True\n", - ")" + ")\n", + "assert correct" ] }, { @@ -911,12 +892,10 @@ "metadata": {}, "outputs": [], "source": [ - "assert (\n", - " is_epsilon_correct(\n", - " lambda theta, eps: (0.5 * (theta + eps) * (1 + sm.cos(theta))) / (sm.sin(theta) + eps)\n", - " )\n", - " == True\n", - ")" + "correct = is_epsilon_correct(\n", + " lambda theta, eps: (0.5 * (theta + eps) * (1 + sm.cos(theta))) / (sm.sin(theta) + eps)\n", + ")\n", + "assert correct" ] }, { diff --git a/pylintrc b/pylintrc deleted file mode 100644 index b6f8205e5..000000000 --- a/pylintrc +++ /dev/null @@ -1,608 +0,0 @@ -[MASTER] - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. -extension-pkg-allow-list= - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. (This is an alternative name to extension-pkg-allow-list -# for backward compatibility.) -extension-pkg-whitelist= - -# Return non-zero exit code if any of these messages/categories are detected, -# even if score is above --fail-under value. Syntax same as enable. Messages -# specified are enabled, while categories only check already-enabled messages. -fail-on= - -# Specify a score threshold to be exceeded before program exits with error. -fail-under=10.0 - -# Files or directories to be skipped. They should be base names, not paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the ignore-list. The -# regex matches against paths. -ignore-paths= - -# Files or directories matching the regex patterns are skipped. The regex -# matches against base names, not paths. -ignore-patterns= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. -jobs=1 - -# Control the amount of potential inferred values when inferring a single -# object. This can help the performance when dealing with large functions or -# complex, nested conditions. -limit-inference-results=100 - -# List of plugins (as comma separated values of python module names) to load, -# usually to register additional checkers. -load-plugins= - -# Pickle collected data for later comparisons. -persistent=yes - -# Min Python version to use for version dependend checks. Will default to the -# version used to run pylint. -py-version=3.8 - -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode=yes - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once). You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable=raw-checker-failed, - bad-inline-option, - locally-disabled, - file-ignored, - suppressed-message, - useless-suppression, - deprecated-pragma, - use-symbolic-message-instead, - - # Overzealous checks - fixme, - too-few-public-methods, - useless-return, - - # Unnecessary checks - import-outside-toplevel, - invalid-name, - logging-format-interpolation, - logging-fstring-interpolation, - missing-timeout, - no-else-break, - no-else-continue, - no-else-raise, - no-else-return, - too-many-public-methods, - unnecessary-pass, - unspecified-encoding, - wrong-import-position, - unnecessary-lambda-assignment, - use-dict-literal, - - # These have some false positives and mypy seems to handle them much better - abstract-method, - arguments-differ, - unpacking-non-sequence, - unsubscriptable-object, - arguments-differ, - not-callable, - undefined-variable, - - # isort handles this - ungrouped-imports, - - # Would be nice to drive these to 0 - arguments-renamed, - consider-using-f-string, - cyclic-import, - line-too-long, - missing-class-docstring, - missing-function-docstring, - missing-module-docstring, - redefined-outer-name, - too-many-arguments, - too-many-branches, - too-many-instance-attributes, - too-many-lines, - too-many-locals, - too-many-return-statements, - too-many-statements, - unused-argument, - wrong-import-order, - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable=c-extension-no-member - - -[REPORTS] - -# Python expression which should return a score less than or equal to 10. You -# have access to the variables 'error', 'warning', 'refactor', and 'convention' -# which contain the number of messages in each category, as well as 'statement' -# which is the total number of statements analyzed. This score is used by the -# global evaluation report (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Tells whether to display a full report or only the messages. -reports=no - -# Activate the evaluation score. -score=yes - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - -# Complete name of functions that never returns. When checking for -# inconsistent-return-statements if a never returning function is called then -# it will be considered as an explicit return statement and no message will be -# printed. -never-returning-functions=sys.exit,argparse.parse_error - - -[SPELLING] - -# Limits count of emitted suggestions for spelling mistakes. -max-spelling-suggestions=4 - -# Spelling dictionary name. Available dictionaries: none. To make it work, -# install the 'python-enchant' package. -spelling-dict= - -# List of comma separated words that should be considered directives if they -# appear and the beginning of a comment and should not be checked. -spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains the private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to the private dictionary (see the -# --spelling-private-dict-file option) instead of raising a message. -spelling-store-unknown-words=no - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid defining new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of names allowed to shadow builtins -allowed-redefined-builtins= - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_, - _cb - -# A regular expression matching the name of dummy variables (i.e. expected to -# not be used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore. -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME, - XXX, - TODO - -# Regular expression of note tags to take in consideration. -#notes-rgx= - - -[STRING] - -# This flag controls whether inconsistent-quotes generates a warning when the -# character used as a quote delimiter is used inconsistently within a module. -check-quote-consistency=no - -# This flag controls whether the implicit-str-concat should generate a warning -# on implicit string concatenation in sequences defined over several lines. -check-str-concat-over-line-jumps=no - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# Tells whether to warn about missing members when the owner of the attribute -# is inferred to be None. -ignore-none=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis). It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules=symforce.cc_sym,cc_sym,symengine,torch # pylint can't figure this out but mypy can, so just leave it to mypy - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - -# List of decorators that change the signature of a decorated function. -signature-mutators= - - -[BASIC] - -# Naming style matching correct argument names. -argument-naming-style=snake_case - -# Regular expression matching correct argument names. Overrides argument- -# naming-style. -#argument-rgx= - -# Naming style matching correct attribute names. -attr-naming-style=snake_case - -# Regular expression matching correct attribute names. Overrides attr-naming- -# style. -#attr-rgx= - -# Bad variable names which should always be refused, separated by a comma. -bad-names= - -# Bad variable names regexes, separated by a comma. If names match any regex, -# they will always be refused -bad-names-rgxs= - -# Naming style matching correct class attribute names. -class-attribute-naming-style=any - -# Regular expression matching correct class attribute names. Overrides class- -# attribute-naming-style. -#class-attribute-rgx= - -# Naming style matching correct class constant names. -class-const-naming-style=UPPER_CASE - -# Regular expression matching correct class constant names. Overrides class- -# const-naming-style. -#class-const-rgx= - -# Naming style matching correct class names. -class-naming-style=PascalCase - -# Regular expression matching correct class names. Overrides class-naming- -# style. -#class-rgx= - -# Naming style matching correct constant names. -const-naming-style=UPPER_CASE - -# Regular expression matching correct constant names. Overrides const-naming- -# style. -#const-rgx= - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - -# Naming style matching correct function names. -function-naming-style=snake_case - -# Regular expression matching correct function names. Overrides function- -# naming-style. -#function-rgx= - -# Good variable names which should always be accepted, separated by a comma. -good-names=i, - j, - k, - ex, - Run, - _ - -# Good variable names regexes, separated by a comma. If names match any regex, -# they will always be accepted -good-names-rgxs= - -# Include a hint for the correct naming format with invalid-name. -include-naming-hint=no - -# Naming style matching correct inline iteration names. -inlinevar-naming-style=any - -# Regular expression matching correct inline iteration names. Overrides -# inlinevar-naming-style. -#inlinevar-rgx= - -# Naming style matching correct method names. -method-naming-style=snake_case - -# Regular expression matching correct method names. Overrides method-naming- -# style. -#method-rgx= - -# Naming style matching correct module names. -module-naming-style=snake_case - -# Regular expression matching correct module names. Overrides module-naming- -# style. -#module-rgx= - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -# These decorators are taken in consideration only for invalid-name. -property-classes=abc.abstractproperty - -# Naming style matching correct variable names. -variable-naming-style=snake_case - -# Regular expression matching correct variable names. Overrides variable- -# naming-style. -#variable-rgx= - - -[LOGGING] - -# The type of string formatting that logging methods do. `old` means using % -# formatting, `new` is for `{}` formatting. -logging-format-style=old - -# Logging modules to check that the string format arguments are in logging -# function parameter format. -logging-modules=logging - - -[FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. -max-line-length=100 - -# Maximum number of lines in a module. -max-module-lines=1000 - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[SIMILARITIES] - -# Comments are removed from the similarity computation -ignore-comments=yes - -# Docstrings are removed from the similarity computation -ignore-docstrings=yes - -# Imports are removed from the similarity computation -ignore-imports=no - -# Signatures are removed from the similarity computation -ignore-signatures=no - -# Minimum lines number of a similarity. -min-similarity-lines=25 - - -[CLASSES] - -# Warn about protected attribute access inside special methods -check-protected-access-in-special-methods=no - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__, - __new__, - setUp, - __post_init__ - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict, - _fields, - _replace, - _source, - _make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=cls - - -[IMPORTS] - -# List of modules that can be imported at any level, not just the top level -# one. -allow-any-import-level= - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma. -deprecated-modules= - -# Output a graph (.gv or any supported image format) of external dependencies -# to the given file (report RP0402 must not be disabled). -ext-import-graph= - -# Output a graph (.gv or any supported image format) of all (i.e. internal and -# external) dependencies to the given file (report RP0402 must not be -# disabled). -import-graph= - -# Output a graph (.gv or any supported image format) of internal dependencies -# to the given file (report RP0402 must not be disabled). -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - -# Couples of modules and preferred modules, separated by a comma. -preferred-modules= - - -[DESIGN] - -# List of qualified class names to ignore when counting class parents (see -# R0901) -ignored-parents= - -# Maximum number of arguments for function / method. -max-args=5 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Maximum number of boolean expressions in an if statement (see R0916). -max-bool-expr=5 - -# Maximum number of branch for function / method body. -max-branches=12 - -# Maximum number of locals for function / method body. -max-locals=15 - -# Maximum number of parents for a class (see R0901). -max-parents=8 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body. -max-returns=6 - -# Maximum number of statements in function / method body. -max-statements=50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "BaseException, Exception". -overgeneral-exceptions=builtins.BaseException, - builtins.Exception diff --git a/pyproject.toml b/pyproject.toml index 56575ff8b..960f20361 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,15 +52,62 @@ Source = "https://github.com/symforce-org/symforce" [tool.ruff] line-length = 100 -exclude = ["third_party", "build", ".eggs"] +exclude = ["third_party", "build", ".eggs", "lcmtypes", "*.pyi"] extend-include = ["*.ipynb"] [tool.ruff.lint] +preview = true +typing-modules = ["symforce.typing"] + select = [ + "A", # flake8 + "B", # flake8-bugbear + "E4", # pycodestyle - ERROR - Imports - E401, E402 + "E7", # pycodestyle - ERROR - Statements - E701-E743 + "E9", # pycodestyle - ERROR - Runtime - E901, E902 + "F", # pyflakes - ALL - F401-F901 "I", # isort + "PLC", # pylint - convention + "PLE", # pylint - error + "PLR", # pylint - refactor + "PLW", # pylint - warning "RUF100", # unused-noqa + "SLF", # flake8-self +] + +ignore = [ + # Leave ignored: + "B008", # function-call-in-default-argument + "E402", # Module level import not at top of file + "E731", # Do not assign a `lambda` expression, use a `def` + "E741", # Ambiguous variable name: `x` + "PLC0415", # import-outside-top-level + "PLC2701", # Private name import `_x` from external module `y` + "PLR2004", # magic-value-comparison + "PLW1514", # unspecified-encoding + "PLW1641", # eq-without-hash + "PLW2901", # redefined-loop-name + + # Maybe enable later + "ARG", # flake8-unused-arguments + "B011", # Do not `assert False`, raise `AssertionError()` ] +[tool.ruff.lint.flake8-builtins] +builtins-ignorelist = ["__doc__"] + + +[tool.ruff.lint.per-file-ignores] + +# Unused imports in __init__.py +"__init__.py" = ["F401"] + +# Unbound loop variables in benchmark notebooks +"symforce/benchmarks/notebooks/*.ipynb" = ["B023"] + +# Imports shadowing builtins (like display) +"**/*.ipynb" = ["A004"] + [tool.ruff.lint.isort] known-first-party = ["sym", "symforce"] force-single-line = true @@ -76,6 +123,13 @@ section-order = [ [tool.ruff.lint.isort.sections] "generated" = ["lcmtypes"] +[tool.ruff.lint.pylint] +max-args = 10 +max-branches = 20 +max-locals = 20 +max-public-methods = 100 +max-returns = 10 + # -------------------------------------------------------------------------------- # Mypy # -------------------------------------------------------------------------------- diff --git a/setup.py b/setup.py index 8f8062bc3..beda773de 100644 --- a/setup.py +++ b/setup.py @@ -122,7 +122,7 @@ def run(self) -> None: # Assuming Makefiles build_args += ["--", f"-j{multiprocessing.cpu_count()}"] - self.build_args = build_args # pylint: disable=attribute-defined-outside-init + self.build_args = build_args env = os.environ.copy() env["CXXFLAGS"] = '{} -DVERSION_INFO=\\"{}\\"'.format( @@ -226,19 +226,19 @@ class SymForceEggInfo(egg_info): def initialize_options(self) -> None: super().initialize_options() - self.rewrite_local_dependencies = False # pylint: disable=attribute-defined-outside-init + self.rewrite_local_dependencies = False def finalize_options(self) -> None: super().finalize_options() if not isinstance(self.rewrite_local_dependencies, bool): - self.rewrite_local_dependencies = ( # pylint: disable=attribute-defined-outside-init - bool(distutils.util.strtobool(self.rewrite_local_dependencies)) + self.rewrite_local_dependencies = bool( + distutils.util.strtobool(self.rewrite_local_dependencies) ) if "SYMFORCE_REWRITE_LOCAL_DEPENDENCIES" in os.environ: - self.rewrite_local_dependencies = ( # pylint: disable=attribute-defined-outside-init - bool(distutils.util.strtobool(os.environ["SYMFORCE_REWRITE_LOCAL_DEPENDENCIES"])) + self.rewrite_local_dependencies = bool( + distutils.util.strtobool(os.environ["SYMFORCE_REWRITE_LOCAL_DEPENDENCIES"]) ) def run(self) -> None: @@ -456,8 +456,8 @@ def fixed_readme() -> str: # 6.13 fixes pip >=23.1 support "pip-tools>=6.13", "pybind11-stubgen>=1.0", - "pylint~=2.16", - "ruff~=0.5.3", + # 0.7.2 introduces this bug: https://github.com/astral-sh/ruff/pull/15090 + "ruff==0.7.1", "types-jinja2", "types-requests", "types-setuptools", diff --git a/symforce/__init__.py b/symforce/__init__.py index 170421f8d..4387fcd11 100644 --- a/symforce/__init__.py +++ b/symforce/__init__.py @@ -131,7 +131,7 @@ def _find_symengine() -> ModuleType: try: spec.loader.exec_module(symengine) - except: # pylint: disable=bare-except + except: # If executing the module fails for any reason, it shouldn't be in `sys.modules` del sys.modules["symengine"] raise @@ -145,7 +145,7 @@ def _find_symengine() -> ModuleType: def _set_symbolic_api(sympy_module: T.Literal["sympy", "symengine"]) -> None: # Set this as the default symbolic API - global _symbolic_api # pylint: disable=global-statement + global _symbolic_api # noqa: PLW0603 _symbolic_api = sympy_module @@ -163,7 +163,7 @@ def _use_symengine() -> None: def _use_sympy() -> None: # Import just to make sure it's importable and fail here if it's not (as opposed to failing # later) - import sympy as sympy_py # pylint: disable=unused-import + import sympy as sympy_py _set_symbolic_api("sympy") @@ -260,7 +260,7 @@ def _set_epsilon(new_epsilon: T.Any) -> None: Args: new_epsilon: The new default epsilon to use """ - global _epsilon # pylint: disable=global-statement + global _epsilon # noqa: PLW0603 if _have_used_epsilon and new_epsilon != _epsilon: raise AlreadyUsedEpsilon( diff --git a/symforce/_sympy_count_ops.py b/symforce/_sympy_count_ops.py index 5ba2be0ae..731f660d7 100644 --- a/symforce/_sympy_count_ops.py +++ b/symforce/_sympy_count_ops.py @@ -68,7 +68,7 @@ def _coeff_isneg(a: Basic) -> bool: @T.no_type_check -def count_ops(expr: T.Any, visual: bool = False) -> T.Union[Expr, int]: +def count_ops(expr: T.Any, visual: bool = False) -> T.Union[Expr, int]: # noqa: PLR0912, PLR0915 """ Return a representation (integer or expression) of the operations in expr. Parameters @@ -129,8 +129,7 @@ def count_ops(expr: T.Any, visual: bool = False) -> T.Union[Expr, int]: expr = sympify(expr) - # pylint: disable=too-many-nested-blocks - if isinstance(expr, Expr) and not expr.is_Relational: + if isinstance(expr, Expr) and not expr.is_Relational: # noqa: PLR1702 ops = [] args = [expr] NEG = Symbol("NEG") @@ -198,8 +197,8 @@ def count_ops(expr: T.Any, visual: bool = False) -> T.Union[Expr, int]: o = Symbol(a.func.__name__.upper()) # count the args ops.append(o * (len(a.args) - 1)) - elif a.args and ( # pylint: disable=too-many-boolean-expressions - a.is_Pow # pylint: disable=consider-merging-isinstance + elif a.args and ( # noqa: PLR0916 + a.is_Pow or a.is_Function or isinstance(a, Derivative) or isinstance(a, Integral) @@ -229,7 +228,7 @@ def count_ops(expr: T.Any, visual: bool = False) -> T.Union[Expr, int]: ops.append(o) elif not isinstance(expr, Basic): ops = [] - else: # it's Basic not isinstance(expr, Expr): + else: # it's Basic not isinstance(expr, Expr): # noqa: PLR5501 if not isinstance(expr, Basic): raise TypeError("Invalid type of expr") else: diff --git a/symforce/benchmarks/matrix_multiplication/generate_matrix_multiplication_benchmark.py b/symforce/benchmarks/matrix_multiplication/generate_matrix_multiplication_benchmark.py index 85bc924eb..838a5a6bc 100644 --- a/symforce/benchmarks/matrix_multiplication/generate_matrix_multiplication_benchmark.py +++ b/symforce/benchmarks/matrix_multiplication/generate_matrix_multiplication_benchmark.py @@ -51,7 +51,7 @@ def get_matrices() -> T.List[T.Tuple[str, Path, scipy.sparse.csr_matrix]]: matrices.append( ( matrix_name.replace(" ", "").replace("-", "_"), - filename, # pylint: disable=undefined-loop-variable + filename, matrix.tocsr(), ) ) @@ -81,7 +81,7 @@ def generate_matrix( matrix_name: str, matrix: scipy.sparse.csr_matrix, symforce_result_is_sparse: bool, - i: int, + runs_multiplier_index: int, ) -> None: """ Generate functions for the given matrix sparsity pattern to compute A, B, and A^T B, in sparse @@ -199,7 +199,9 @@ def compute_A(*symbols: T.List[sf.Symbol]) -> sf.Matrix: matrix_name_camel=python_util.snakecase_to_camelcase(matrix_name), N=matrix.shape[0], M=matrix.shape[1], - n_runs_multiplier=[100.0, 100.0, 100.0, 10.0, 10.0, 10.0, 1.0, 1.0][i], + n_runs_multiplier=[100.0, 100.0, 100.0, 10.0, 10.0, 10.0, 1.0, 1.0][ + runs_multiplier_index + ], symforce_result_is_sparse=symforce_result_is_sparse, n_symbols=N_SYMBOLS, cant_allocate_on_stack=cant_allocate_on_stack, @@ -214,4 +216,10 @@ def generate(output_dir: Path) -> None: for i, (matrix_name, _filename, matrix) in enumerate(get_matrices()): logger.debug(f"Generating matrix {matrix_name}") - generate_matrix(output_dir, matrix_name, matrix, symforce_result_is_sparse=i > 2, i=i) + generate_matrix( + output_dir, + matrix_name, + matrix, + symforce_result_is_sparse=i > 2, + runs_multiplier_index=i, + ) diff --git a/symforce/benchmarks/notebooks/jax_inverse_compose.ipynb b/symforce/benchmarks/notebooks/jax_inverse_compose.ipynb index 0ea8d1fde..e44cb8739 100644 --- a/symforce/benchmarks/notebooks/jax_inverse_compose.ipynb +++ b/symforce/benchmarks/notebooks/jax_inverse_compose.ipynb @@ -21,7 +21,6 @@ "\n", "import jax\n", "import jaxlie\n", - "import numpy as onp\n", "from jax import numpy as np" ] }, diff --git a/symforce/benchmarks/notebooks/jax_matmul.ipynb b/symforce/benchmarks/notebooks/jax_matmul.ipynb index 9906005bd..053993938 100644 --- a/symforce/benchmarks/notebooks/jax_matmul.ipynb +++ b/symforce/benchmarks/notebooks/jax_matmul.ipynb @@ -22,7 +22,6 @@ "import time\n", "\n", "import jax\n", - "import numpy as onp\n", "from jax import numpy as np" ] }, diff --git a/symforce/benchmarks/notebooks/jax_robot_localization.ipynb b/symforce/benchmarks/notebooks/jax_robot_localization.ipynb index ae03fa120..8927f63d8 100644 --- a/symforce/benchmarks/notebooks/jax_robot_localization.ipynb +++ b/symforce/benchmarks/notebooks/jax_robot_localization.ipynb @@ -24,7 +24,6 @@ "\n", "import jax\n", "import jaxlie\n", - "import numpy as onp\n", "from jax import numpy as np" ] }, diff --git a/symforce/benchmarks/notebooks/matmul_plots.ipynb b/symforce/benchmarks/notebooks/matmul_plots.ipynb index 943c5203a..d8e4a30da 100644 --- a/symforce/benchmarks/notebooks/matmul_plots.ipynb +++ b/symforce/benchmarks/notebooks/matmul_plots.ipynb @@ -19,10 +19,7 @@ "import pickle\n", "from pathlib import Path\n", "\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", "import pandas as pd\n", - "import scipy.io\n", "from plotly import express as ex" ] }, @@ -45,9 +42,6 @@ "metadata": {}, "outputs": [], "source": [ - "# This file should be generated by `run_benchmarks.py`\n", - "from symforce.benchmarks.run_benchmarks import MatmulBenchmarkConfig\n", - "\n", "with (Path(\"../../..\") / \"benchmark_outputs\" / \"matrix_multiplication_benchmark_results.pkl\").open(\n", " \"rb\"\n", ") as f:\n", @@ -192,7 +186,7 @@ " cpu = \"N/A\"\n", " s.append(cpu)\n", "\n", - " def format(c):\n", + " def format_time(c):\n", " if c in best_cpu.values():\n", " c = round(c * 1e6, 1) # ms to ns\n", " return f\"\\\\textbf{{{c}}}\"\n", @@ -202,7 +196,7 @@ " c = round(c * 1e6, 1) # ms to ns\n", " return f\"{c}\"\n", "\n", - " s = [format(c) for c in s]\n", + " s = [format_time(c) for c in s]\n", " print(\" & \".join(s) + \" \\\\\\\\\")" ] } diff --git a/symforce/benchmarks/run_benchmarks.py b/symforce/benchmarks/run_benchmarks.py index fdd649aa2..23e58d764 100644 --- a/symforce/benchmarks/run_benchmarks.py +++ b/symforce/benchmarks/run_benchmarks.py @@ -214,8 +214,8 @@ def main(benchmark: T.Optional[str] = None, out_dir: str = "benchmark_outputs") else: run_benchmark(benchmark, CONFIG[benchmark], out_path) else: - for ( # pylint: disable=redefined-argument-from-local - benchmark, + for ( + benchmark, # noqa: PLR1704 benchmark_config, ) in CONFIG.items(): run_benchmark(benchmark, benchmark_config, out_path) diff --git a/symforce/cam/polynomial_camera_cal.py b/symforce/cam/polynomial_camera_cal.py index d0960c1e4..157b36d99 100644 --- a/symforce/cam/polynomial_camera_cal.py +++ b/symforce/cam/polynomial_camera_cal.py @@ -59,17 +59,14 @@ def __init__( if critical_undistorted_radius is not None: self.critical_undistorted_radius = critical_undistorted_radius + elif any( + isinstance(c, sf.Expr) and not isinstance(c, sf.Number) for c in distortion_coeffs + ): + raise ValueError( + "critical_undistorted_radius must be provided if the distortion_coeffs are not all numerical" + ) else: - if any( - isinstance(c, sf.Expr) and not isinstance(c, sf.Number) for c in distortion_coeffs - ): - raise ValueError( - "critical_undistorted_radius must be provided if the distortion_coeffs are not all numerical" - ) - else: - self.critical_undistorted_radius = self._compute_critical_undistorted_radius( - max_fov - ) + self.critical_undistorted_radius = self._compute_critical_undistorted_radius(max_fov) @classmethod def from_distortion_coeffs( diff --git a/symforce/cam/spherical_camera_cal.py b/symforce/cam/spherical_camera_cal.py index d628519bb..5a1e7c28c 100644 --- a/symforce/cam/spherical_camera_cal.py +++ b/symforce/cam/spherical_camera_cal.py @@ -80,15 +80,14 @@ def __init__( if critical_theta is not None: self.critical_theta = critical_theta + elif any( + isinstance(c, sf.Expr) and not isinstance(c, sf.Number) for c in distortion_coeffs + ): + raise ValueError( + "critical_theta must be provided if the distortion_coeffs are not all numerical" + ) else: - if any( - isinstance(c, sf.Expr) and not isinstance(c, sf.Number) for c in distortion_coeffs - ): - raise ValueError( - "critical_theta must be provided if the distortion_coeffs are not all numerical" - ) - else: - self.critical_theta = self._compute_critical_theta(max_theta) + self.critical_theta = self._compute_critical_theta(max_theta) @classmethod def from_distortion_coeffs( diff --git a/symforce/cc_sym.py b/symforce/cc_sym.py index 400a4e37e..48e81ac18 100644 --- a/symforce/cc_sym.py +++ b/symforce/cc_sym.py @@ -16,16 +16,16 @@ try: # If cc_sym is availble on the python path, use it - from cc_sym import * # pylint: disable=wildcard-import -except ImportError as ex: + from cc_sym import * # noqa: F403 +except ImportError: try: sys.path.append(os.fspath(path_util.cc_sym_install_dir())) except path_util.MissingManifestException as ex2: raise ImportError from ex2 - from cc_sym import * # pylint: disable=wildcard-import + from cc_sym import * # noqa: F403 # Set log level, in case the user has set the level in python -set_log_level( # pylint: disable=undefined-variable +set_log_level( # noqa: F405 _logging.getLevelName(_logger.getEffectiveLevel()) ) diff --git a/symforce/codegen/backends/cpp/cpp_code_printer.py b/symforce/codegen/backends/cpp/cpp_code_printer.py index c13137f00..7437df3e6 100644 --- a/symforce/codegen/backends/cpp/cpp_code_printer.py +++ b/symforce/codegen/backends/cpp/cpp_code_printer.py @@ -40,7 +40,8 @@ def _print_expr(expr: sympy.Expr) -> str: setattr(self, method_name, _print_expr) - def _print_Rational(self, expr: sympy.Rational) -> str: + @staticmethod + def _print_Rational(expr: sympy.Rational) -> str: """ Customizations: * Cast all literals to Scalar at compile time instead of using a suffix at codegen time @@ -160,8 +161,9 @@ def _print_MatrixElement(self, expr: sympy.matrices.expressions.matexpr.MatrixEl ) -class ComplexCppCodePrinter(CppCodePrinter): # pylint: disable=too-many-ancestors - def _print_Integer(self, expr: sympy.Integer) -> str: +class ComplexCppCodePrinter(CppCodePrinter): + @staticmethod + def _print_Integer(expr: sympy.Integer) -> str: """ Customizations: * Cast all integers to Scalar, since binary ops between integers and complex aren't @@ -169,7 +171,8 @@ def _print_Integer(self, expr: sympy.Integer) -> str: """ return f"Scalar({expr.p})" - def _print_ImaginaryUnit(self, expr: sympy.Expr) -> str: + @staticmethod + def _print_ImaginaryUnit(expr: sympy.Expr) -> str: """ Customizations: * Print 1i instead of I diff --git a/symforce/codegen/backends/cpp/cpp_config.py b/symforce/codegen/backends/cpp/cpp_config.py index 514ff54b9..d6de3cec5 100644 --- a/symforce/codegen/backends/cpp/cpp_config.py +++ b/symforce/codegen/backends/cpp/cpp_config.py @@ -100,7 +100,8 @@ def printer(self) -> CodePrinter: def format_data_accessor(prefix: str, index: int) -> str: return f"{prefix}.Data()[{index}]" - def format_matrix_accessor(self, key: str, i: int, j: int, *, shape: T.Tuple[int, int]) -> str: + @staticmethod + def format_matrix_accessor(key: str, i: int, j: int, *, shape: T.Tuple[int, int]) -> str: CppConfig._assert_indices_in_bounds(i, j, shape) return f"{key}({i}, {j})" diff --git a/symforce/codegen/backends/python/python_code_printer.py b/symforce/codegen/backends/python/python_code_printer.py index 3c2d34822..ae2a43c4c 100644 --- a/symforce/codegen/backends/python/python_code_printer.py +++ b/symforce/codegen/backends/python/python_code_printer.py @@ -13,7 +13,8 @@ class PythonCodePrinter(_PythonCodePrinter): behavior for codegen compatibility and efficiency. """ - def _print_Rational(self, expr: sympy.Rational) -> str: + @staticmethod + def _print_Rational(expr: sympy.Rational) -> str: """ Customizations: * Decimal points for Python2 support, doesn't exist in some sympy versions. diff --git a/symforce/codegen/backends/python/python_config.py b/symforce/codegen/backends/python/python_config.py index ba1944474..5cd0a84a3 100644 --- a/symforce/codegen/backends/python/python_config.py +++ b/symforce/codegen/backends/python/python_config.py @@ -64,16 +64,19 @@ def backend_name(cls) -> str: def template_dir(cls) -> Path: return CURRENT_DIR / "templates" - def templates_to_render(self, generated_file_name: str) -> T.List[T.Tuple[str, str]]: + @staticmethod + def templates_to_render(generated_file_name: str) -> T.List[T.Tuple[str, str]]: return [ ("function/FUNCTION.py.jinja", f"{generated_file_name}.py"), ("function/__init__.py.jinja", "__init__.py"), ] - def printer(self) -> CodePrinter: + @staticmethod + def printer() -> CodePrinter: return python_code_printer.PythonCodePrinter() - def format_matrix_accessor(self, key: str, i: int, j: int, *, shape: T.Tuple[int, int]) -> str: + @staticmethod + def format_matrix_accessor(key: str, i: int, j: int, *, shape: T.Tuple[int, int]) -> str: PythonConfig._assert_indices_in_bounds(i, j, shape) return f"{key}[{i}, {j}]" diff --git a/symforce/codegen/backends/python/templates/cam_package/ops/CLASS/camera_ops.py.jinja b/symforce/codegen/backends/python/templates/cam_package/ops/CLASS/camera_ops.py.jinja index de293bab8..c8ba2ac4a 100644 --- a/symforce/codegen/backends/python/templates/cam_package/ops/CLASS/camera_ops.py.jinja +++ b/symforce/codegen/backends/python/templates/cam_package/ops/CLASS/camera_ops.py.jinja @@ -4,12 +4,14 @@ # ---------------------------------------------------------------------------- #} {%- import "../../../util/util.jinja" as util with context -%} +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class CameraOps(object): diff --git a/symforce/codegen/backends/python/templates/function/FUNCTION.py.jinja b/symforce/codegen/backends/python/templates/function/FUNCTION.py.jinja index cc3047862..b52c3b680 100644 --- a/symforce/codegen/backends/python/templates/function/FUNCTION.py.jinja +++ b/symforce/codegen/backends/python/templates/function/FUNCTION.py.jinja @@ -4,11 +4,7 @@ # ---------------------------------------------------------------------------- #} {%- import "../util/util.jinja" as util with context -%} -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 import math import typing as T diff --git a/symforce/codegen/backends/python/templates/geo_package/CLASS.py.jinja b/symforce/codegen/backends/python/templates/geo_package/CLASS.py.jinja index ec0dea1cc..39abcf4cc 100644 --- a/symforce/codegen/backends/python/templates/geo_package/CLASS.py.jinja +++ b/symforce/codegen/backends/python/templates/geo_package/CLASS.py.jinja @@ -2,6 +2,9 @@ # SymForce - Copyright 2022, Skydio, Inc. # This source code is under the Apache 2.0 license found in the LICENSE file. # ---------------------------------------------------------------------------- #} + +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import random import typing as T @@ -183,6 +186,6 @@ class {{ cls.__name__ }}(object): if isinstance(other, {{ cls.__name__ }}): return self.compose(other) elif isinstance(other, numpy.ndarray) and hasattr(self, "compose_with_point"): - return getattr(self, "compose_with_point")(other).reshape(other.shape) + return self.compose_with_point(other).reshape(other.shape) else: raise NotImplementedError('Cannot compose {} with {}.'.format(type(self), type(other))) diff --git a/symforce/codegen/backends/python/templates/ops/CLASS/group_ops.py.jinja b/symforce/codegen/backends/python/templates/ops/CLASS/group_ops.py.jinja index 084496d23..c5de95c2f 100644 --- a/symforce/codegen/backends/python/templates/ops/CLASS/group_ops.py.jinja +++ b/symforce/codegen/backends/python/templates/ops/CLASS/group_ops.py.jinja @@ -4,12 +4,14 @@ # ---------------------------------------------------------------------------- #} {%- import "../../util/util.jinja" as util with context -%} +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class GroupOps(object): diff --git a/symforce/codegen/backends/python/templates/ops/CLASS/lie_group_ops.py.jinja b/symforce/codegen/backends/python/templates/ops/CLASS/lie_group_ops.py.jinja index 9a125ecd7..3f6e4248f 100644 --- a/symforce/codegen/backends/python/templates/ops/CLASS/lie_group_ops.py.jinja +++ b/symforce/codegen/backends/python/templates/ops/CLASS/lie_group_ops.py.jinja @@ -4,12 +4,14 @@ # ---------------------------------------------------------------------------- #} {%- import "../../util/util.jinja" as util with context -%} +# ruff: noqa: PLR0915, F401, PLW0211, PLR0914 + import math import typing as T import numpy -import sym # pylint: disable=useless-suppression,unused-import +import sym class LieGroupOps(object): diff --git a/symforce/codegen/backends/python/templates/tests/cam_package_python_test.py.jinja b/symforce/codegen/backends/python/templates/tests/cam_package_python_test.py.jinja index 8170b78bf..72ae98d5e 100644 --- a/symforce/codegen/backends/python/templates/tests/cam_package_python_test.py.jinja +++ b/symforce/codegen/backends/python/templates/tests/cam_package_python_test.py.jinja @@ -25,16 +25,16 @@ class CamPackageTest(unittest.TestCase): _DISTORTION_COEFF_VALS = {{ _DISTORTION_COEFF_VALS }} @staticmethod - def cam_cal_from_points(cam_cls, focal_length, principal_point): - # type: (T.Type, T.Sequence[float], T.Sequence[float]) -> T.Any + def cam_cal_from_points( + cam_cls: T.Type, focal_length: T.Sequence[float], principal_point: T.Sequence[float] + ) -> T.Any: return cam_cls( focal_length=focal_length, principal_point=principal_point, **CamPackageTest._DISTORTION_COEFF_VALS.get(cam_cls.__name__, {})) {% for cls in all_types %} - def test_getters_{{ cls.__name__ }}(self): - # type: () -> None + def test_getters_{{ cls.__name__ }}(self) -> None: focal_length = [1.0, 2.0] principal_point = [3.0, 4.0] cam_cal = self.cam_cal_from_points( @@ -54,8 +54,7 @@ class CamPackageTest(unittest.TestCase): for x in new_cam_cal.data: self.assertIsInstance(x, float) - def test_storage_ops_{{ cls.__name__ }}(self): - # type: () -> None + def test_storage_ops_{{ cls.__name__ }}(self) -> None: cam_cal = self.cam_cal_from_points( sym.{{ cls.__name__ }}, focal_length=[1.0, 2.0], principal_point=[3.0, 4.0] ) @@ -79,9 +78,7 @@ class CamPackageTest(unittest.TestCase): )%} {% set epsilon = 1e-8 %} - def test_lie_group_ops_{{ cls.__name__ }}(self): - # type: () -> None - + def test_lie_group_ops_{{ cls.__name__ }}(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. cam_cal = sym.{{ cls.__name__ }}.from_storage({{ symbolic_cam_cal.to_storage() | map("float") | list }}) @@ -124,9 +121,7 @@ class CamPackageTest(unittest.TestCase): np.array({{ ops.LieGroupOps.local_coordinates(second_symbolic_cam_cal, symbolic_cam_cal, epsilon=epsilon) | map("float") | list }}) ) - def test_pixel_from_camera_point_{{ cls.__name__ }}(self): - # type: () -> None - + def test_pixel_from_camera_point_{{ cls.__name__ }}(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs # of the symbolic class's methods. {% set point = Matrix([0.6, 0.8, 0.2]) %} @@ -150,9 +145,7 @@ class CamPackageTest(unittest.TestCase): self.assertEqual(pixel_D_point.shape, (2, 3)) {% if cls.has_camera_ray_from_pixel() %} - def test_camera_ray_from_pixel_{{ cls.__name__ }}(self): - # type: () -> None - + def test_camera_ray_from_pixel_{{ cls.__name__ }}(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. {% set pixel = Matrix([0.6, 0.8]) %} diff --git a/symforce/codegen/backends/python/templates/tests/geo_package_python_test.py.jinja b/symforce/codegen/backends/python/templates/tests/geo_package_python_test.py.jinja index 5d46b7f94..8ec15fe4e 100644 --- a/symforce/codegen/backends/python/templates/tests/geo_package_python_test.py.jinja +++ b/symforce/codegen/backends/python/templates/tests/geo_package_python_test.py.jinja @@ -27,15 +27,13 @@ class GeoPackageTest(unittest.TestCase): since the math is tested comprehensively in symbolic form. """ - def setUp(self): - # type: () -> None + def setUp(self) -> None: np.random.seed(42) # Store verbosity flag so tests can use self.verbose = ("-v" in sys.argv) or ("--verbose" in sys.argv) {% for cls in all_types %} - def test_storage_ops_{{ cls.__name__ }}(self): - # type: () -> None + def test_storage_ops_{{ cls.__name__ }}(self) -> None: """ Tests: sym.{{ cls.__name__ }} StorageOps @@ -59,8 +57,7 @@ class GeoPackageTest(unittest.TestCase): value3 = geo_class.from_storage(vec) self.assertNotEqual(value.data, value3.data) - def test_group_ops_{{ cls.__name__ }}(self): - # type: () -> None + def test_group_ops_{{ cls.__name__ }}(self) -> None: """ Tests: sym.{{ cls.__name__ }} GroupOps @@ -82,8 +79,7 @@ class GeoPackageTest(unittest.TestCase): self.assertEqual(identity, identity.inverse()) self.assertEqual(identity, identity.between(identity)) - def test_lie_group_ops_{{ cls.__name__ }}(self): - # type: () -> None + def test_lie_group_ops_{{ cls.__name__ }}(self) -> None: """ Tests: sym.{{ cls.__name__ }} LieGroupOps @@ -118,8 +114,7 @@ class GeoPackageTest(unittest.TestCase): {# Skip for Unit3 because the following tests are Rot/Pose specific #} {% if "Rot" in cls.__name__ or "Pose" in cls.__name__ %} - def test_custom_methods_{{ cls.__name__ }}(self): - # type: () -> None + def test_custom_methods_{{ cls.__name__ }}(self) -> None: """ Tests: sym.{{ cls.__name__ }} custom methods diff --git a/symforce/codegen/backends/python/templates/util/util.jinja b/symforce/codegen/backends/python/templates/util/util.jinja index 2826fb9a3..4347ac4b7 100644 --- a/symforce/codegen/backends/python/templates/util/util.jinja +++ b/symforce/codegen/backends/python/templates/util/util.jinja @@ -141,7 +141,7 @@ def {{ function_name_and_args(spec) }}: {% if 1 in shape %} {% if use_numba %} {# NOTE(brad): Numba will complain if we reshape name inside of a conditional #} -if not ({{ name }}.shape == {{ shape }} or {{ name }}.shape == ({{ shape | max }},)): +if not ({{ name }}.shape == {{ shape }} or {{ name }}.shape == ({{ shape | max }},)): # noqa: PLR1714 raise IndexError("{{ name }} is expected to have shape {{ shape }} or ({{ shape | max }},)") {{ name }} = {{ name }}.reshape({{ shape }}) {% else %} @@ -269,7 +269,7 @@ elif {{ name }}.shape != {{ shape }}: #} {% macro flatten_if_ndarray(array, size) %} if isinstance({{ array }}, numpy.ndarray): - if {{ array }}.shape in [({{ size }}, 1), (1, {{ size }})]: + if {{ array }}.shape in {({{ size }}, 1), (1, {{ size }})}: {{ array }} = {{ array }}.flatten() elif {{ array }}.shape != ({{ size }},): raise IndexError("Expected {{ array }} to be a vector of length {{ size }}; instead had shape {}".format({{ array }}.shape)) diff --git a/symforce/codegen/backends/pytorch/pytorch_code_printer.py b/symforce/codegen/backends/pytorch/pytorch_code_printer.py index 37a46730d..f213e45c6 100644 --- a/symforce/codegen/backends/pytorch/pytorch_code_printer.py +++ b/symforce/codegen/backends/pytorch/pytorch_code_printer.py @@ -57,7 +57,7 @@ def _print_known_const(self: PyTorchCodePrinter, expr: sympy.Expr) -> str: def _print_known_func(self: PyTorchCodePrinter, expr: sympy.Expr) -> str: name = _known_functions_torch[expr.__class__.__name__] - return f"torch.{name}({', '.join(map(self._print, expr.args))})" # pylint: disable=protected-access + return f"torch.{name}({', '.join(map(self._print, expr.args))})" class PyTorchCodePrinter(CodePrinter): @@ -71,7 +71,7 @@ class PyTorchCodePrinter(CodePrinter): known_functions = _known_functions_torch language = "Python" - _default_settings = dict(CodePrinter._default_settings, human=False) + _default_settings = dict(CodePrinter._default_settings, human=False) # noqa: SLF001 def __init__(self, settings: T.Optional[T.Mapping[str, T.Any]] = None): if settings and settings.get("human", False): @@ -86,7 +86,8 @@ def doprint(self, expr: sympy.Expr, assign_to: T.Optional[T.Any] = None) -> str: ) return result - def _format_code(self, lines: T.List[str]) -> T.List[str]: + @staticmethod + def _format_code(lines: T.List[str]) -> T.List[str]: return lines def _print_Mod(self, expr: sympy.Mod) -> str: @@ -95,11 +96,12 @@ def _print_Mod(self, expr: sympy.Mod) -> str: def _print_sign(self, expr: sympy.sign) -> str: return f"torch.sign({self._print(expr.args[0])})" - def _print_Pow(self, expr: sympy.Pow, rational: bool = False) -> str: # pylint: disable=unused-argument + def _print_Pow(self, expr: sympy.Pow, rational: bool = False) -> str: # TODO(aaron): Optimize this? return f"torch.pow({self._print(expr.base)}, {self._print(expr.exp)})" - def _print_Rational(self, expr: sympy.Rational) -> str: + @staticmethod + def _print_Rational(expr: sympy.Rational) -> str: # This is py3-only, need decimal points if we want py2 return f"torch.tensor({expr.p}/{expr.q}, **tensor_kwargs)" @@ -109,7 +111,8 @@ def _print_Float(self, flt: sympy.Float) -> str: def _print_frac(self, expr: sympy.frac) -> str: return self._print_Mod(sympy.Mod(expr.args[0], 1)) - def _print_Integer(self, expr: sympy.Integer) -> str: + @staticmethod + def _print_Integer(expr: sympy.Integer) -> str: """ Customizations: * Cast all integers to Tensor @@ -123,7 +126,8 @@ def _print_NumberSymbol(self, expr: sympy.Expr) -> str: """ return f"torch.tensor({super()._print_NumberSymbol(expr)}, **tensor_kwargs)" - def _print_Zero(self, expr: sympy.Expr) -> str: + @staticmethod + def _print_Zero(expr: sympy.Expr) -> str: """ Customizations: * Cast Zero to Tensor diff --git a/symforce/codegen/backends/pytorch/pytorch_config.py b/symforce/codegen/backends/pytorch/pytorch_config.py index a3eea02d2..14a9c1918 100644 --- a/symforce/codegen/backends/pytorch/pytorch_config.py +++ b/symforce/codegen/backends/pytorch/pytorch_config.py @@ -43,16 +43,19 @@ def backend_name(cls) -> str: def template_dir(cls) -> Path: return CURRENT_DIR / "templates" - def templates_to_render(self, generated_file_name: str) -> T.List[T.Tuple[str, str]]: + @staticmethod + def templates_to_render(generated_file_name: str) -> T.List[T.Tuple[str, str]]: return [ ("function/FUNCTION.py.jinja", f"{generated_file_name}.py"), ("function/__init__.py.jinja", "__init__.py"), ] - def printer(self) -> CodePrinter: + @staticmethod + def printer() -> CodePrinter: return pytorch_code_printer.PyTorchCodePrinter() - def format_matrix_accessor(self, key: str, i: int, j: int, *, shape: T.Tuple[int, int]) -> str: + @staticmethod + def format_matrix_accessor(key: str, i: int, j: int, *, shape: T.Tuple[int, int]) -> str: PyTorchConfig._assert_indices_in_bounds(i, j, shape) if (shape[0] == 1) ^ (shape[1] == 1): return f"{key}[..., {max(i, j)}]" diff --git a/symforce/codegen/backends/pytorch/templates/function/FUNCTION.py.jinja b/symforce/codegen/backends/pytorch/templates/function/FUNCTION.py.jinja index 2ca7b9cbd..7f301bf4e 100644 --- a/symforce/codegen/backends/pytorch/templates/function/FUNCTION.py.jinja +++ b/symforce/codegen/backends/pytorch/templates/function/FUNCTION.py.jinja @@ -4,13 +4,9 @@ # ---------------------------------------------------------------------------- #} {%- import "../util/util.jinja" as util with context -%} -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 -import math # pylint: disable=unused-import +import math import typing as T import torch diff --git a/symforce/codegen/cam_package_codegen.py b/symforce/codegen/cam_package_codegen.py index c49c10f21..fe6b11c79 100644 --- a/symforce/codegen/cam_package_codegen.py +++ b/symforce/codegen/cam_package_codegen.py @@ -163,7 +163,7 @@ def cam_class_data(cls: T.Type, config: CodegenConfig) -> T.Dict[str, T.Any]: return data -def class_template_data(cls: T.Type, functions_to_doc: T.Sequence[function]) -> T.Dict[str, T.Any]: +def class_template_data(cls: T.Type, functions_to_doc: T.Sequence[function]) -> T.Dict[str, T.Any]: # noqa: F821 data = Codegen.common_data() data["doc"] = {} assert cls.__doc__ is not None diff --git a/symforce/codegen/codegen_util.py b/symforce/codegen/codegen_util.py index a4844dddd..9a42263e6 100644 --- a/symforce/codegen/codegen_util.py +++ b/symforce/codegen/codegen_util.py @@ -543,7 +543,7 @@ def _load_generated_package_internal(name: str, path: Path) -> T.Tuple[T.Any, T. ensure name imports the correct modules. """ if path.is_dir(): - path = path / "__init__.py" + path = path / "__init__.py" # noqa: PLR6104 parts = name.split(".") if len(parts) > 1: @@ -687,7 +687,7 @@ def load_generated_lcmtype( """ # We need to import the lcmtypes package first so that sys.path is set up correctly, since this # is a namespace package - import lcmtypes # pylint: disable=unused-import + import lcmtypes # noqa: F401 return getattr( load_generated_package( diff --git a/symforce/codegen/format_util.py b/symforce/codegen/format_util.py index 9856281ca..93389e65d 100644 --- a/symforce/codegen/format_util.py +++ b/symforce/codegen/format_util.py @@ -60,7 +60,7 @@ def _find_ruff() -> Path: `shutil.which` should cover most cases, but not all, the better solution would require `ruff` putting the binary in `data` like `clang-format` does """ - global _ruff_path # pylint: disable=global-statement + global _ruff_path # noqa: PLW0603 if _ruff_path is not None: return _ruff_path diff --git a/symforce/codegen/geo_factors_codegen.py b/symforce/codegen/geo_factors_codegen.py index ffb0ffda0..929a57cc4 100644 --- a/symforce/codegen/geo_factors_codegen.py +++ b/symforce/codegen/geo_factors_codegen.py @@ -53,7 +53,7 @@ def get_prior_docstring() -> str: def between_factor( a: T.Element, b: T.Element, a_T_b: T.Element, sqrt_info: sf.Matrix, epsilon: sf.Scalar = 0 ) -> sf.Matrix: - assert type(a) == type(b) == type(a_T_b) # pylint: disable=unidiomatic-typecheck + assert type(a) is type(b) is type(a_T_b) assert sqrt_info.rows == sqrt_info.cols == ops.LieGroupOps.tangent_dim(a) # Compute error @@ -70,7 +70,7 @@ def between_factor( def prior_factor( value: T.Element, prior: T.Element, sqrt_info: sf.Matrix, epsilon: sf.Scalar = 0 ) -> sf.Matrix: - assert type(value) == type(prior) # pylint: disable=unidiomatic-typecheck + assert type(value) is type(prior) assert sqrt_info.rows == sqrt_info.cols == ops.LieGroupOps.tangent_dim(value) # Compute error diff --git a/symforce/codegen/geo_package_codegen.py b/symforce/codegen/geo_package_codegen.py index 211a68c4e..2809b159e 100644 --- a/symforce/codegen/geo_package_codegen.py +++ b/symforce/codegen/geo_package_codegen.py @@ -236,7 +236,7 @@ def generate(config: CodegenConfig, output_dir: T.Optional[Path] = None) -> Path data["custom_generated_methods"] = custom_generated_methods.get(cls, {}) if cls == sf.Pose2: data["imported_classes"] = [sf.Rot2] - elif cls in (sf.Pose3, sf.Unit3): + elif cls in {sf.Pose3, sf.Unit3}: data["imported_classes"] = [sf.Rot3] for base_dir, relative_path in ( diff --git a/symforce/codegen/slam_factors_codegen.py b/symforce/codegen/slam_factors_codegen.py index 073a99861..c940581b0 100644 --- a/symforce/codegen/slam_factors_codegen.py +++ b/symforce/codegen/slam_factors_codegen.py @@ -159,7 +159,7 @@ def inverse_range_landmark_reprojection_error_residual( return whitened_residual -def inverse_range_landmark_gnc_residual( +def inverse_range_landmark_gnc_residual( # noqa: PLR0913, PLR0917 source_pose: sf.Pose3, source_calibration: sf.CameraCal, target_pose: sf.Pose3, diff --git a/symforce/codegen/template_util.py b/symforce/codegen/template_util.py index 506e5892c..424a3e842 100644 --- a/symforce/codegen/template_util.py +++ b/symforce/codegen/template_util.py @@ -10,7 +10,6 @@ import functools import os import textwrap -import warnings from pathlib import Path import jinja2 @@ -38,9 +37,9 @@ class FileType(enum.Enum): @staticmethod def from_extension(extension: str) -> FileType: - if extension in ("c", "cpp", "cxx", "cc", "tcc", "h", "hpp", "hxx", "hh"): + if extension in {"c", "cpp", "cxx", "cc", "tcc", "h", "hpp", "hxx", "hh"}: return FileType.CPP - elif extension in ("cu", "cuh"): + elif extension in {"cu", "cuh"}: return FileType.CUDA elif extension == "py": return FileType.PYTHON @@ -70,9 +69,9 @@ def comment_prefix(self) -> str: """ Return the comment prefix for this file type. """ - if self in (FileType.CPP, FileType.CUDA, FileType.LCM): + if self in {FileType.CPP, FileType.CUDA, FileType.LCM}: return "//" - elif self in (FileType.PYTHON, FileType.PYTHON_INTERFACE, FileType.TOML): + elif self in {FileType.PYTHON, FileType.PYTHON_INTERFACE, FileType.TOML}: return "#" else: raise NotImplementedError(f"Unknown comment prefix for {self}") @@ -97,11 +96,11 @@ def autoformat( # place for auto-format logic, but I thought it was better centralized here than down below # hidden in a function. We might want to somehow pass the config through to render a # template so we can move things into the backend code. (tag=centralize-language-diffs) - if self in (FileType.CPP, FileType.CUDA): + if self in {FileType.CPP, FileType.CUDA}: return format_util.format_cpp( file_contents, filename=str(CURRENT_DIR / format_filename) ) - elif self in (FileType.PYTHON, FileType.PYTHON_INTERFACE): + elif self in {FileType.PYTHON, FileType.PYTHON_INTERFACE}: return format_util.format_py(file_contents, filename=str(CURRENT_DIR / format_filename)) elif self == FileType.LCM: return file_contents @@ -116,7 +115,8 @@ class RelEnvironment(jinja2.Environment): https://stackoverflow.com/questions/8512677/how-to-include-a-template-with-relative-path-in-jinja2 """ - def join_path(self, template: T.Union[jinja2.Template, str], parent: str) -> str: + @staticmethod + def join_path(template: T.Union[jinja2.Template, str], parent: str) -> str: return os.path.normpath(os.path.join(os.path.dirname(parent), str(template))) @@ -208,11 +208,6 @@ def render_template( template_name=template_path, output_path=output_path, ) - else: - warnings.warn( - "Config.autoformat == False is deprecated, this option will be removed in a future release", - DeprecationWarning, - ) if output_path: output_path = Path(output_path) diff --git a/symforce/codegen/types_package_codegen.py b/symforce/codegen/types_package_codegen.py index 23e30f951..1cec43f36 100644 --- a/symforce/codegen/types_package_codegen.py +++ b/symforce/codegen/types_package_codegen.py @@ -164,7 +164,7 @@ def generate_types( else: typenames_dict[name] = f"{name}_t" namespaces_dict[name] = package_name - for typename, data in types_dict.items(): + for data in types_dict.values(): # Iterate through types in types_dict. If type is external, use the shared_types to # get the namespace. unformatted_typenames = T.cast(T.List[str], data["unformatted_typenames"]) diff --git a/symforce/geo/__init__.py b/symforce/geo/__init__.py index eeb6a3db3..11207c2ce 100644 --- a/symforce/geo/__init__.py +++ b/symforce/geo/__init__.py @@ -21,7 +21,7 @@ from . import unsupported from .complex import Complex from .dual_quaternion import DualQuaternion -from .matrix import * # pylint: disable=wildcard-import +from .matrix import * # noqa: F403 from .pose2 import Pose2 from .pose3 import Pose3 from .quaternion import Quaternion diff --git a/symforce/geo/complex.py b/symforce/geo/complex.py index 2d59169d9..5d97d0f54 100644 --- a/symforce/geo/complex.py +++ b/symforce/geo/complex.py @@ -152,7 +152,7 @@ def __neg__(self) -> Complex: """ return self.__class__(-self.real, -self.imag) - def __div__(self, scalar: T.Scalar) -> Complex: + def __truediv__(self, scalar: T.Scalar) -> Complex: """ Scalar element-wise division. @@ -164,8 +164,6 @@ def __div__(self, scalar: T.Scalar) -> Complex: """ return self.__class__(self.real / scalar, self.imag / scalar) - __truediv__ = __div__ - @classmethod def random_uniform(cls, low: T.Scalar, high: T.Scalar) -> Complex: """ diff --git a/symforce/geo/dual_quaternion.py b/symforce/geo/dual_quaternion.py index 598d4e868..8fb3bf2f5 100644 --- a/symforce/geo/dual_quaternion.py +++ b/symforce/geo/dual_quaternion.py @@ -82,14 +82,12 @@ def __mul__(self, right: DualQuaternion) -> DualQuaternion: """ return self.compose(right) - def __div__(self, scalar: T.Scalar) -> DualQuaternion: + def __truediv__(self, scalar: T.Scalar) -> DualQuaternion: """ Scalar division. """ return DualQuaternion(self.real_q / scalar, self.inf_q / scalar) - __truediv__ = __div__ - def squared_norm(self) -> T.Scalar: """ Squared norm when considering the dual quaternion as 8-tuple. diff --git a/symforce/geo/matrix.py b/symforce/geo/matrix.py index 629f9351b..e53b8d305 100644 --- a/symforce/geo/matrix.py +++ b/symforce/geo/matrix.py @@ -65,7 +65,7 @@ class Matrix(Storage): # this class variable as a strong internal consistency check. SHAPE = (-1, -1) - def __new__(cls, *args: _T.Any, **kwargs: _T.Any) -> Matrix: + def __new__(cls, *args: _T.Any, **kwargs: _T.Any) -> Matrix: # noqa: PLR0915 """ Beast of a method for creating a Matrix. Handles a variety of construction use cases and *always* returns a fixed size child class of Matrix rather than Matrix itself. The @@ -116,12 +116,10 @@ def __new__(cls, *args: _T.Any, **kwargs: _T.Any) -> Matrix: f"Expected {cls.storage_dim()} elements for {cls}, got {len(array)}" ) rows, cols = cls.SHAPE + elif len(array) == 0: + rows, cols = 0, 0 else: - # Only set the second dimension to 1 if the array is nonempty - if len(array) == 0: - rows, cols = 0, 0 - else: - rows, cols = len(array), 1 + rows, cols = len(array), 1 flat_list = list(array) # 4) If there are two arguments and this is not a fixed size matrix, treat it as a size @@ -760,16 +758,16 @@ def __rmul__( return self.__class__(left * self.mat) @_T.overload - def __div__( + def __truediv__( self, right: _T.Union[Matrix, sf.sympy.MutableDenseMatrix] ) -> Matrix: # pragma: no cover pass @_T.overload - def __div__(self: MatrixT, right: _T.Scalar) -> MatrixT: # pragma: no cover + def __truediv__(self: MatrixT, right: _T.Scalar) -> MatrixT: # pragma: no cover pass - def __div__( + def __truediv__( self, right: _T.Union[MatrixT, _T.Scalar, Matrix, sf.sympy.MutableDenseMatrix] ) -> _T.Union[MatrixT, Matrix]: """ @@ -782,8 +780,8 @@ def __div__( else: return self.__class__(self.mat * _T.cast(sf.sympy.MutableDenseMatrix, right).inv()) - def _symengine_(self) -> symengine.Matrix: - symengine = symforce._find_symengine() # pylint: disable=protected-access + def _symengine_(self) -> symengine.Matrix: # noqa: PLW3201 + symengine = symforce._find_symengine() # noqa: SLF001 return symengine.S(self.mat) def compute_AtA(self, lower_only: bool = False) -> Matrix: @@ -867,8 +865,6 @@ def solve(self, b: Matrix, method: str = "LU") -> Matrix: """ return self.__class__(self.mat.solve(b, method=method)) - __truediv__ = __div__ - @staticmethod def are_parallel(a: Vector3, b: Vector3, tolerance: _T.Scalar) -> _T.Scalar: """ @@ -952,11 +948,11 @@ def _is_fixed_size(cls) -> bool: """ return cls.SHAPE[0] > 0 and cls.SHAPE[1] > 0 - def _ipython_display_(self) -> None: + def _ipython_display_(self) -> None: # noqa: PLW3201 """ Display ``self.mat`` in IPython, with SymPy's pretty printing """ - display(self.mat) # type: ignore[name-defined] # pylint: disable=undefined-variable # not defined outside of ipython + display(self.mat) # type: ignore[name-defined] # noqa: F821 # not defined outside of ipython @staticmethod def init_printing() -> None: diff --git a/symforce/geo/quaternion.py b/symforce/geo/quaternion.py index 82507c24f..6d5d38170 100644 --- a/symforce/geo/quaternion.py +++ b/symforce/geo/quaternion.py @@ -127,7 +127,7 @@ def __add__(self, right: Quaternion) -> Quaternion: """ return self.__class__(xyz=self.xyz + right.xyz, w=self.w + right.w) - def __div__(self, scalar: T.Scalar) -> Quaternion: + def __truediv__(self, scalar: T.Scalar) -> Quaternion: """ Scalar division. @@ -140,8 +140,6 @@ def __div__(self, scalar: T.Scalar) -> Quaternion: denom = sf.S.One / scalar return self.__class__(xyz=self.xyz * denom, w=self.w * denom) - __truediv__ = __div__ - @classmethod def zero(cls) -> Quaternion: """ diff --git a/symforce/internal/symbolic.py b/symforce/internal/symbolic.py index d835b0db4..110645926 100644 --- a/symforce/internal/symbolic.py +++ b/symforce/internal/symbolic.py @@ -23,8 +23,7 @@ available as well as :mod:`symforce.symbolic.sympy`. """ -# pylint: disable=unused-import -# pylint: disable=unused-wildcard-import +# ruff: noqa: F401, F403, F405, SLF001 import contextlib import functools @@ -33,7 +32,7 @@ from symforce import logger from symforce import typing as T -if symforce._symbolic_api is None: # pylint: disable=protected-access +if symforce._symbolic_api is None: import textwrap logger.warning( @@ -54,10 +53,10 @@ # See `symforce/__init__.py` for more information, this is used to check whether things that this # module depends on are modified after importing -symforce._have_imported_symbolic = True # pylint: disable=protected-access +symforce._have_imported_symbolic = True if not T.TYPE_CHECKING and symforce.get_symbolic_api() == "symengine": - sympy = symforce._find_symengine() # pylint: disable=protected-access + sympy = symforce._find_symengine() # Import sympy, for methods that convert to sympy types or call sympy functions below import sympy as _sympy_py @@ -299,7 +298,7 @@ def named_scope(scope: str) -> T.Iterator[None]: def set_scope(scope: str) -> None: - global __scopes__ # pylint: disable=global-statement + global __scopes__ # noqa: PLW0603 __scopes__ = scope.split(".") if scope else [] @@ -315,7 +314,7 @@ def get_scope() -> str: if not T.TYPE_CHECKING and sympy.__package__ == "symengine": - class Symbol(sympy.Symbol): # pylint: disable=function-redefined,too-many-ancestors + class Symbol(sympy.Symbol): def __init__( self, name: str, @@ -339,9 +338,7 @@ def __init__( _original_symbols = sympy.symbols @functools.wraps(_original_symbols) - def symbols( # pylint: disable=function-redefined - names: str, **args: T.Any - ) -> T.Union[T.Sequence[Symbol], Symbol]: + def symbols(names: str, **args: T.Any) -> T.Union[T.Sequence[Symbol], Symbol]: cls = args.pop("cls", Symbol) return _original_symbols(names, **dict(args, cls=cls)) @@ -404,7 +401,6 @@ def foo(x: Scalar, epsilon: Scalar = sf.epsilon()) -> Scalar: The current default epsilon. This is typically some kind of "Scalar", like a float or a :class:`Symbol `. """ - # pylint: disable=protected-access if isinstance(symforce._epsilon, symforce.SymbolicEpsilon): symforce._epsilon = sympy.Symbol(symforce._epsilon.name) @@ -426,7 +422,7 @@ def foo(x: Scalar, epsilon: Scalar = sf.epsilon()) -> Scalar: # -------------------------------------------------------------------------------- # isort: split -from symforce.logic import * # pylint: disable=wildcard-import +from symforce.logic import * # -------------------------------------------------------------------------------- # Additional custom functions @@ -586,7 +582,7 @@ def limit( e: T.Any, z: T.Any, z0: T.Any, - dir: str = "+", # pylint: disable=redefined-builtin + dir: str = "+", # noqa: A002 ) -> Scalar: logger.warning("Converting to sympy to use .limit") return sympy.S(_sympy_py.limit(_sympy_py.S(e), _sympy_py.S(z), _sympy_py.S(z0), dir=dir)) @@ -688,14 +684,14 @@ def solve(*args: T.Any, **kwargs: T.Any) -> T.List[Scalar]: # Hack in some key derivatives that sympy doesn't do. For all these cases the derivatives # here are correct except at the discrete switching point, which is correct for our # numerical purposes. - setattr(floor, "_eval_derivative", lambda s, v: S.Zero) - setattr(sign, "_eval_derivative", lambda s, v: S.Zero) + floor._eval_derivative = lambda s, v: S.Zero + sign._eval_derivative = lambda s, v: S.Zero def mod_derivative(self: T.Any, x: T.Any) -> T.Any: p, q = self.args - return self._eval_rewrite_as_floor(p, q).diff(x) # pylint: disable=protected-access + return self._eval_rewrite_as_floor(p, q).diff(x) - setattr(Mod, "_eval_derivative", mod_derivative) + Mod._eval_derivative = mod_derivative else: raise symforce.InvalidSymbolicApiError(sympy.__package__) @@ -712,8 +708,8 @@ def _flatten_storage_type_subs( """ new_subs_dict = {} # Import these lazily, since initialization.py is imported from symforce/__init__.py - from symforce import ops # pylint: disable=cyclic-import - from symforce import typing_util # pylint: disable=cyclic-import + from symforce import ops + from symforce import typing_util for key, value in subs_pairs: if key is None: @@ -782,7 +778,7 @@ def _get_subs_dict(*args: T.Any, dont_flatten_args: bool = False, **kwargs: T.An # For some reason this doesn't exist unless we import the symengine_wrapper directly as a # local variable, i.e. just `import symengine.lib.symengine_wrapper` does not let us access # symengine.lib.symengine_wrapper - import symengine.lib.symengine_wrapper as wrapper # pylint: disable=no-name-in-module + import symengine.lib.symengine_wrapper as wrapper original_get_dict = wrapper.get_dict wrapper.get_dict = lambda *args, **kwargs: original_get_dict(_get_subs_dict(*args, **kwargs)) diff --git a/symforce/ops/__init__.py b/symforce/ops/__init__.py index 3adc2aa11..4bd0ea993 100644 --- a/symforce/ops/__init__.py +++ b/symforce/ops/__init__.py @@ -71,7 +71,7 @@ def __subclasshook__(cls, subclass: T.Type) -> bool: LieGroupOps.register(type(None), NoneTypeLieGroupOps) -class LieGroupSymClass(abc.ABC): +class LieGroupSymClass(abc.ABC): # noqa: B024 """ Metaclass for generated numeric geo classes diff --git a/symforce/ops/impl/nonetype_lie_group_ops.py b/symforce/ops/impl/nonetype_lie_group_ops.py index badddf7a9..9c68ba667 100644 --- a/symforce/ops/impl/nonetype_lie_group_ops.py +++ b/symforce/ops/impl/nonetype_lie_group_ops.py @@ -28,7 +28,7 @@ def to_storage(a: None) -> T.List[T.Scalar]: @staticmethod def from_storage(a: NoneElementOrType, elements: T.Sequence[T.Scalar]) -> None: assert len(elements) == 0 - return None + return None # noqa: PLR1711 @staticmethod def symbolic(a: NoneElementOrType, name: str, **kwargs: T.Dict) -> None: diff --git a/symforce/opt/factor.py b/symforce/opt/factor.py index debd5ad19..aa78ce5f2 100644 --- a/symforce/opt/factor.py +++ b/symforce/opt/factor.py @@ -121,7 +121,7 @@ def from_inputs_and_residual( config = cls.default_codegen_config() instance = cls.__new__(cls) - instance._initialize( + instance._initialize( # noqa: SLF001 keys=keys, codegen_obj=Codegen( inputs=inputs, outputs=Values(residual=residual), config=config, **kwargs @@ -195,8 +195,6 @@ def generate( else None, sparse_linearization=sparse_linearization, ) - # Ignore false positive because we define `self.jacobian` in `_initialize()` - # pylint: disable=attribute-defined-outside-init self.generated_jacobians[tuple(optimized_keys)] = codegen_with_linearization.outputs[ "jacobian" ] diff --git a/symforce/opt/optimizer.py b/symforce/opt/optimizer.py index 46b938bbd..ee1e85110 100644 --- a/symforce/opt/optimizer.py +++ b/symforce/opt/optimizer.py @@ -232,7 +232,9 @@ def __init__( if debug_stats is not None: self.params.debug_stats = debug_stats warnings.warn( - "debug_stats argument is deprecated, use params.debug_stats", FutureWarning + "debug_stats argument is deprecated, use params.debug_stats", + FutureWarning, + stacklevel=5, ) if include_jacobians is not None: @@ -240,6 +242,7 @@ def __init__( warnings.warn( "include_jacobians argument is deprecated, use params.include_jacobians", FutureWarning, + stacklevel=5, ) self._initialized = False diff --git a/symforce/python_util.py b/symforce/python_util.py index 71463b473..266087f38 100644 --- a/symforce/python_util.py +++ b/symforce/python_util.py @@ -282,9 +282,9 @@ def get_class_for_method(func: T.Callable) -> T.Type: if inspect.ismethod(func) or ( inspect.isbuiltin(func) and getattr(func, "__self__", None) is not None - and getattr(getattr(func, "__self__"), "__class__", None) is not None + and getattr(func.__self__, "__class__", None) is not None ): - return getattr(getattr(func, "__self__"), "__class__") + return func.__self__.__class__ if inspect.isfunction(func): cls = getattr( inspect.getmodule(func), @@ -293,7 +293,9 @@ def get_class_for_method(func: T.Callable) -> T.Type: ) if isinstance(cls, type): return cls - return getattr(func, "__objclass__") # handle special descriptor objects + + # handle special descriptor objects + return func.__objclass__ # type: ignore[attr-defined] class AttrDict(dict): diff --git a/symforce/slam/imu_preintegration/generate.py b/symforce/slam/imu_preintegration/generate.py index dd5b92e47..815cd599b 100644 --- a/symforce/slam/imu_preintegration/generate.py +++ b/symforce/slam/imu_preintegration/generate.py @@ -13,7 +13,7 @@ from symforce.slam.imu_preintegration.manifold_symbolic import roll_forward_state -def internal_imu_unit_gravity_residual( +def internal_imu_unit_gravity_residual( # noqa: PLR0913, PLR0917 pose_i: sf.Pose3, vel_i: sf.V3, pose_j: sf.Pose3, diff --git a/symforce/slam/imu_preintegration/manifold_symbolic.py b/symforce/slam/imu_preintegration/manifold_symbolic.py index 783d29bc6..5e8dc9140 100644 --- a/symforce/slam/imu_preintegration/manifold_symbolic.py +++ b/symforce/slam/imu_preintegration/manifold_symbolic.py @@ -48,7 +48,7 @@ def roll_forward_state( ) -def internal_imu_residual( +def internal_imu_residual( # noqa: PLR0913, PLR0917 pose_i: sf.Pose3, vel_i: sf.V3, pose_j: sf.Pose3, @@ -224,7 +224,7 @@ def handwritten_new_state_D_state_gyro_accel( return sf.M99(new_state_D_old_state), sf.M93(new_state_D_gyro), sf.M93(new_state_D_accel) -def imu_manifold_preintegration_update( +def imu_manifold_preintegration_update( # noqa: PLR0913, PLR0917 # Initial state DR: sf.Rot3, Dv: sf.V3, diff --git a/symforce/symbolic.py b/symforce/symbolic.py index ec5c44586..e921a27b6 100644 --- a/symforce/symbolic.py +++ b/symforce/symbolic.py @@ -20,9 +20,7 @@ available as well as ``symforce.symbolic.sympy``. """ -# pylint: disable=wildcard-import -# pylint: disable=unused-import -# pylint: disable=unused-wildcard-import +# ruff: noqa: F401, F403 from symforce.internal.symbolic import * diff --git a/symforce/test_util/random_expressions/unary_binary_expression_gen.py b/symforce/test_util/random_expressions/unary_binary_expression_gen.py index 4e8b52bb9..7d08edc93 100644 --- a/symforce/test_util/random_expressions/unary_binary_expression_gen.py +++ b/symforce/test_util/random_expressions/unary_binary_expression_gen.py @@ -59,11 +59,11 @@ def __init__( self.ops = list(self.unary_ops) + list(self.binary_ops) self.ops_dict = {op.name: op for op in self.ops} - self.unary_ops_probs = np.array([op.prob for op in self.unary_ops]) - self.unary_ops_probs = self.unary_ops_probs / sum(self.unary_ops_probs) + self.unary_ops_probs = np.array([op.prob for op in self.unary_ops], dtype=np.float64) + self.unary_ops_probs /= sum(self.unary_ops_probs) - self.binary_ops_probs = np.array([op.prob for op in self.binary_ops]) - self.binary_ops_probs = self.binary_ops_probs / sum(self.binary_ops_probs) + self.binary_ops_probs = np.array([op.prob for op in self.binary_ops], dtype=np.float64) + self.binary_ops_probs /= sum(self.binary_ops_probs) # D[e][n] represents the number of different binary trees with n nodes # that can be generated from e empty nodes @@ -138,7 +138,7 @@ def sample_next_pos( e = np.random.choice(2 * nb_empty, p=np_probs) arity = 1 if e < nb_empty else 2 - e = e % nb_empty + e %= nb_empty return e, arity @@ -180,7 +180,7 @@ def build_tree_sequence(self, num_ops_target: int) -> T.List: # insert leaves into tree leaves = [np.random.choice(self.leaves) for _ in range(t_leaves)] - for i in range(len(stack)): # pylint: disable=consider-using-enumerate + for i in range(len(stack)): if stack[i] is None: stack[i] = leaves.pop() @@ -209,8 +209,7 @@ def _seq_to_expr( elif t in self.leaves: return T.cast(sf.Scalar, t), seq[1:] else: - assert f"Unknown: {t}" - return 0, [] # Just for mypy.. + assert False, f"Unknown: {t}" return _seq_to_expr(seq)[0] diff --git a/symforce/test_util/stubs_util.py b/symforce/test_util/stubs_util.py index e967621d4..13dc49a37 100644 --- a/symforce/test_util/stubs_util.py +++ b/symforce/test_util/stubs_util.py @@ -31,7 +31,7 @@ def handle_docstring( assert isinstance( self, pybind11_stubgen.parser.mixins.parse.ExtractSignaturesFromPybind11Docstrings ) - return self._strip_empty_lines(value.splitlines()) # pylint: disable=protected-access + return self._strip_empty_lines(value.splitlines()) return None pybind11_stubgen.parser.mixins.parse.BaseParser.handle_docstring = handle_docstring # type: ignore[method-assign] diff --git a/symforce/test_util/test_case.py b/symforce/test_util/test_case.py index 591e0b4d7..beeec16cc 100644 --- a/symforce/test_util/test_case.py +++ b/symforce/test_util/test_case.py @@ -46,7 +46,7 @@ def main(*args: T.Any, **kwargs: T.Any) -> None: # can be removed once the fix is in a release: # https://github.com/python/cpython/commit/159e3db1f7697b9aecdf674bb833fbb87f3dcad3 if sys.version_info >= (3, 12, 0) and sys.version_info < (3, 12, 2): - sys.modules[unittest.main.__module__]._NO_TESTS_EXITCODE = 0 # type: ignore[attr-defined] # pylint: disable=protected-access + sys.modules[unittest.main.__module__]._NO_TESTS_EXITCODE = 0 # type: ignore[attr-defined] # noqa: SLF001 SymforceTestCaseMixin.main(*args, **kwargs) diff --git a/symforce/test_util/test_case_mixin.py b/symforce/test_util/test_case_mixin.py index cf9563bda..7df658bbb 100644 --- a/symforce/test_util/test_case_mixin.py +++ b/symforce/test_util/test_case_mixin.py @@ -196,11 +196,14 @@ def compare_or_update(self, path: T.Openable, data: str) -> None: if data != expected_data: diff = difflib.unified_diff( - expected_data.splitlines(), data.splitlines(), "expected", "got", lineterm="" + expected_data.splitlines(keepends=True), + data.splitlines(keepends=True), + "expected", + "got", ) self.fail( "\n" - + "\n".join(diff) + + "".join(diff) + f"\n\n{80*'='}\nData did not match for file {path}, see diff above. Use " "`--update` to write the changes to the working directory and commit if desired" ) diff --git a/symforce/type_helpers.py b/symforce/type_helpers.py index 4b744c492..303fdee38 100644 --- a/symforce/type_helpers.py +++ b/symforce/type_helpers.py @@ -77,7 +77,7 @@ def symbolic_inputs( parameters = [ p for p in inspect.signature(func).parameters.values() - if p.kind in (inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD) + if p.kind in {inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_OR_KEYWORD} ] if input_types is None: diff --git a/symforce/typing.py b/symforce/typing.py index 0244fa67e..3f5e197f7 100644 --- a/symforce/typing.py +++ b/symforce/typing.py @@ -7,17 +7,19 @@ Common type definitions. """ +# ruff: noqa: F403, F405, A005 + import abc import dataclasses import os # Expose all types. -from typing import * # pylint: disable=wildcard-import,unused-wildcard-import +from typing import * # This is kind of a heavy/unnecessary dependency,here so only import when type checking so we can # resolve the annotation below if TYPE_CHECKING: - import numpy as np + import numpy as np # noqa: F401 # TODO(hayk,aaron): Either make this a union of "Scalar types", or different typevars for numeric # and symbolic scalars or something diff --git a/symforce/values/values.py b/symforce/values/values.py index caf9bf09e..537a32263 100644 --- a/symforce/values/values.py +++ b/symforce/values/values.py @@ -169,7 +169,7 @@ def get_index_from_items(items: T.Iterable[T.Tuple[str, T.Any]]) -> T.Dict[str, elif isinstance(value, (list, tuple)): if not ( all( - type(v) == type(value[0]) # pylint: disable=unidiomatic-typecheck + type(v) == type(value[0]) # noqa: E721 for v in value ) or all(typing_util.scalar_like(v) for v in value) @@ -807,7 +807,6 @@ def _apply_to_leaves(value: T.Any, func: T.Callable) -> T.Any: if isinstance(value, Values): return Values({k: Values._apply_to_leaves(v, func) for k, v in value.items()}) elif isinstance(value, (list, tuple)): - # pylint: disable=too-many-function-args return type(value)([Values._apply_to_leaves(v, func) for v in value]) elif isinstance(value, T.Dataclass): return Values( @@ -889,7 +888,6 @@ def _to_dict_recursive(value: T.Any) -> T.Any: if isinstance(value, Values): return {k: _to_dict_recursive(v) for k, v in value.items()} elif isinstance(value, (list, tuple)): - # pylint: disable=too-many-function-args return type(value)(_to_dict_recursive(v) for v in value) elif isinstance(value, T.Dataclass): return { diff --git a/test/cam_package_python_test.py b/test/cam_package_python_test.py index a26e66b65..f6293416f 100644 --- a/test/cam_package_python_test.py +++ b/test/cam_package_python_test.py @@ -38,16 +38,16 @@ class CamPackageTest(unittest.TestCase): } @staticmethod - def cam_cal_from_points(cam_cls, focal_length, principal_point): - # type: (T.Type, T.Sequence[float], T.Sequence[float]) -> T.Any + def cam_cal_from_points( + cam_cls: T.Type, focal_length: T.Sequence[float], principal_point: T.Sequence[float] + ) -> T.Any: return cam_cls( focal_length=focal_length, principal_point=principal_point, **CamPackageTest._DISTORTION_COEFF_VALS.get(cam_cls.__name__, {}), ) - def test_getters_ATANCameraCal(self): - # type: () -> None + def test_getters_ATANCameraCal(self) -> None: focal_length = [1.0, 2.0] principal_point = [3.0, 4.0] cam_cal = self.cam_cal_from_points( @@ -67,8 +67,7 @@ def test_getters_ATANCameraCal(self): for x in new_cam_cal.data: self.assertIsInstance(x, float) - def test_storage_ops_ATANCameraCal(self): - # type: () -> None + def test_storage_ops_ATANCameraCal(self) -> None: cam_cal = self.cam_cal_from_points( sym.ATANCameraCal, focal_length=[1.0, 2.0], principal_point=[3.0, 4.0] ) @@ -85,9 +84,7 @@ def test_storage_ops_ATANCameraCal(self): self.assertNotEqual(cam_cal, cam_cal_different) - def test_lie_group_ops_ATANCameraCal(self): - # type: () -> None - + def test_lie_group_ops_ATANCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. cam_cal = sym.ATANCameraCal.from_storage([1.0, 2.0, 3.0, 4.0, 0.5]) @@ -120,9 +117,7 @@ def test_lie_group_ops_ATANCameraCal(self): np.array([-2.3, -3.5, 0.6000000000000001, 0.20000000000000018, 0.0]), ) - def test_pixel_from_camera_point_ATANCameraCal(self): - # type: () -> None - + def test_pixel_from_camera_point_ATANCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs # of the symbolic class's methods. @@ -143,9 +138,7 @@ def test_pixel_from_camera_point_ATANCameraCal(self): self.assertEqual(pixel_D_cal.shape, (2, 5)) self.assertEqual(pixel_D_point.shape, (2, 3)) - def test_camera_ray_from_pixel_ATANCameraCal(self): - # type: () -> None - + def test_camera_ray_from_pixel_ATANCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. @@ -166,8 +159,7 @@ def test_camera_ray_from_pixel_ATANCameraCal(self): self.assertEqual(point_D_cal.shape, (3, 5)) self.assertEqual(point_D_pixel.shape, (3, 2)) - def test_getters_DoubleSphereCameraCal(self): - # type: () -> None + def test_getters_DoubleSphereCameraCal(self) -> None: focal_length = [1.0, 2.0] principal_point = [3.0, 4.0] cam_cal = self.cam_cal_from_points( @@ -187,8 +179,7 @@ def test_getters_DoubleSphereCameraCal(self): for x in new_cam_cal.data: self.assertIsInstance(x, float) - def test_storage_ops_DoubleSphereCameraCal(self): - # type: () -> None + def test_storage_ops_DoubleSphereCameraCal(self) -> None: cam_cal = self.cam_cal_from_points( sym.DoubleSphereCameraCal, focal_length=[1.0, 2.0], principal_point=[3.0, 4.0] ) @@ -205,9 +196,7 @@ def test_storage_ops_DoubleSphereCameraCal(self): self.assertNotEqual(cam_cal, cam_cal_different) - def test_lie_group_ops_DoubleSphereCameraCal(self): - # type: () -> None - + def test_lie_group_ops_DoubleSphereCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. cam_cal = sym.DoubleSphereCameraCal.from_storage([1.0, 2.0, 3.0, 4.0, 5.1, -6.2]) @@ -240,9 +229,7 @@ def test_lie_group_ops_DoubleSphereCameraCal(self): np.array([-2.3, -3.5, 0.6000000000000001, 0.20000000000000018, 0.0, 0.0]), ) - def test_pixel_from_camera_point_DoubleSphereCameraCal(self): - # type: () -> None - + def test_pixel_from_camera_point_DoubleSphereCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs # of the symbolic class's methods. @@ -263,9 +250,7 @@ def test_pixel_from_camera_point_DoubleSphereCameraCal(self): self.assertEqual(pixel_D_cal.shape, (2, 6)) self.assertEqual(pixel_D_point.shape, (2, 3)) - def test_camera_ray_from_pixel_DoubleSphereCameraCal(self): - # type: () -> None - + def test_camera_ray_from_pixel_DoubleSphereCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. @@ -290,8 +275,7 @@ def test_camera_ray_from_pixel_DoubleSphereCameraCal(self): self.assertEqual(point_D_cal.shape, (3, 6)) self.assertEqual(point_D_pixel.shape, (3, 2)) - def test_getters_EquirectangularCameraCal(self): - # type: () -> None + def test_getters_EquirectangularCameraCal(self) -> None: focal_length = [1.0, 2.0] principal_point = [3.0, 4.0] cam_cal = self.cam_cal_from_points( @@ -311,8 +295,7 @@ def test_getters_EquirectangularCameraCal(self): for x in new_cam_cal.data: self.assertIsInstance(x, float) - def test_storage_ops_EquirectangularCameraCal(self): - # type: () -> None + def test_storage_ops_EquirectangularCameraCal(self) -> None: cam_cal = self.cam_cal_from_points( sym.EquirectangularCameraCal, focal_length=[1.0, 2.0], principal_point=[3.0, 4.0] ) @@ -329,9 +312,7 @@ def test_storage_ops_EquirectangularCameraCal(self): self.assertNotEqual(cam_cal, cam_cal_different) - def test_lie_group_ops_EquirectangularCameraCal(self): - # type: () -> None - + def test_lie_group_ops_EquirectangularCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. cam_cal = sym.EquirectangularCameraCal.from_storage([1.0, 2.0, 3.0, 4.0]) @@ -363,9 +344,7 @@ def test_lie_group_ops_EquirectangularCameraCal(self): np.array([-2.3, -3.5, 0.6000000000000001, 0.20000000000000018]), ) - def test_pixel_from_camera_point_EquirectangularCameraCal(self): - # type: () -> None - + def test_pixel_from_camera_point_EquirectangularCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs # of the symbolic class's methods. @@ -386,9 +365,7 @@ def test_pixel_from_camera_point_EquirectangularCameraCal(self): self.assertEqual(pixel_D_cal.shape, (2, 4)) self.assertEqual(pixel_D_point.shape, (2, 3)) - def test_camera_ray_from_pixel_EquirectangularCameraCal(self): - # type: () -> None - + def test_camera_ray_from_pixel_EquirectangularCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. @@ -413,8 +390,7 @@ def test_camera_ray_from_pixel_EquirectangularCameraCal(self): self.assertEqual(point_D_cal.shape, (3, 4)) self.assertEqual(point_D_pixel.shape, (3, 2)) - def test_getters_LinearCameraCal(self): - # type: () -> None + def test_getters_LinearCameraCal(self) -> None: focal_length = [1.0, 2.0] principal_point = [3.0, 4.0] cam_cal = self.cam_cal_from_points( @@ -434,8 +410,7 @@ def test_getters_LinearCameraCal(self): for x in new_cam_cal.data: self.assertIsInstance(x, float) - def test_storage_ops_LinearCameraCal(self): - # type: () -> None + def test_storage_ops_LinearCameraCal(self) -> None: cam_cal = self.cam_cal_from_points( sym.LinearCameraCal, focal_length=[1.0, 2.0], principal_point=[3.0, 4.0] ) @@ -452,9 +427,7 @@ def test_storage_ops_LinearCameraCal(self): self.assertNotEqual(cam_cal, cam_cal_different) - def test_lie_group_ops_LinearCameraCal(self): - # type: () -> None - + def test_lie_group_ops_LinearCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. cam_cal = sym.LinearCameraCal.from_storage([1.0, 2.0, 3.0, 4.0]) @@ -486,9 +459,7 @@ def test_lie_group_ops_LinearCameraCal(self): np.array([-2.3, -3.5, 0.6000000000000001, 0.20000000000000018]), ) - def test_pixel_from_camera_point_LinearCameraCal(self): - # type: () -> None - + def test_pixel_from_camera_point_LinearCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs # of the symbolic class's methods. @@ -509,9 +480,7 @@ def test_pixel_from_camera_point_LinearCameraCal(self): self.assertEqual(pixel_D_cal.shape, (2, 4)) self.assertEqual(pixel_D_point.shape, (2, 3)) - def test_camera_ray_from_pixel_LinearCameraCal(self): - # type: () -> None - + def test_camera_ray_from_pixel_LinearCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. @@ -532,8 +501,7 @@ def test_camera_ray_from_pixel_LinearCameraCal(self): self.assertEqual(point_D_cal.shape, (3, 4)) self.assertEqual(point_D_pixel.shape, (3, 2)) - def test_getters_PolynomialCameraCal(self): - # type: () -> None + def test_getters_PolynomialCameraCal(self) -> None: focal_length = [1.0, 2.0] principal_point = [3.0, 4.0] cam_cal = self.cam_cal_from_points( @@ -553,8 +521,7 @@ def test_getters_PolynomialCameraCal(self): for x in new_cam_cal.data: self.assertIsInstance(x, float) - def test_storage_ops_PolynomialCameraCal(self): - # type: () -> None + def test_storage_ops_PolynomialCameraCal(self) -> None: cam_cal = self.cam_cal_from_points( sym.PolynomialCameraCal, focal_length=[1.0, 2.0], principal_point=[3.0, 4.0] ) @@ -571,9 +538,7 @@ def test_storage_ops_PolynomialCameraCal(self): self.assertNotEqual(cam_cal, cam_cal_different) - def test_lie_group_ops_PolynomialCameraCal(self): - # type: () -> None - + def test_lie_group_ops_PolynomialCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. cam_cal = sym.PolynomialCameraCal.from_storage( @@ -612,9 +577,7 @@ def test_lie_group_ops_PolynomialCameraCal(self): np.array([-2.3, -3.5, 0.6000000000000001, 0.20000000000000018, 0.0, 0.0, 0.0, 0.0]), ) - def test_pixel_from_camera_point_PolynomialCameraCal(self): - # type: () -> None - + def test_pixel_from_camera_point_PolynomialCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs # of the symbolic class's methods. @@ -637,8 +600,7 @@ def test_pixel_from_camera_point_PolynomialCameraCal(self): self.assertEqual(pixel_D_cal.shape, (2, 7)) self.assertEqual(pixel_D_point.shape, (2, 3)) - def test_getters_SphericalCameraCal(self): - # type: () -> None + def test_getters_SphericalCameraCal(self) -> None: focal_length = [1.0, 2.0] principal_point = [3.0, 4.0] cam_cal = self.cam_cal_from_points( @@ -658,8 +620,7 @@ def test_getters_SphericalCameraCal(self): for x in new_cam_cal.data: self.assertIsInstance(x, float) - def test_storage_ops_SphericalCameraCal(self): - # type: () -> None + def test_storage_ops_SphericalCameraCal(self) -> None: cam_cal = self.cam_cal_from_points( sym.SphericalCameraCal, focal_length=[1.0, 2.0], principal_point=[3.0, 4.0] ) @@ -676,9 +637,7 @@ def test_storage_ops_SphericalCameraCal(self): self.assertNotEqual(cam_cal, cam_cal_different) - def test_lie_group_ops_SphericalCameraCal(self): - # type: () -> None - + def test_lie_group_ops_SphericalCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. cam_cal = sym.SphericalCameraCal.from_storage( @@ -782,9 +741,7 @@ def test_lie_group_ops_SphericalCameraCal(self): ), ) - def test_pixel_from_camera_point_SphericalCameraCal(self): - # type: () -> None - + def test_pixel_from_camera_point_SphericalCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs # of the symbolic class's methods. @@ -819,8 +776,7 @@ def test_pixel_from_camera_point_SphericalCameraCal(self): self.assertEqual(pixel_D_cal.shape, (2, 10)) self.assertEqual(pixel_D_point.shape, (2, 3)) - def test_getters_OrthographicCameraCal(self): - # type: () -> None + def test_getters_OrthographicCameraCal(self) -> None: focal_length = [1.0, 2.0] principal_point = [3.0, 4.0] cam_cal = self.cam_cal_from_points( @@ -840,8 +796,7 @@ def test_getters_OrthographicCameraCal(self): for x in new_cam_cal.data: self.assertIsInstance(x, float) - def test_storage_ops_OrthographicCameraCal(self): - # type: () -> None + def test_storage_ops_OrthographicCameraCal(self) -> None: cam_cal = self.cam_cal_from_points( sym.OrthographicCameraCal, focal_length=[1.0, 2.0], principal_point=[3.0, 4.0] ) @@ -858,9 +813,7 @@ def test_storage_ops_OrthographicCameraCal(self): self.assertNotEqual(cam_cal, cam_cal_different) - def test_lie_group_ops_OrthographicCameraCal(self): - # type: () -> None - + def test_lie_group_ops_OrthographicCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs of # of the symbolic class's methods. cam_cal = sym.OrthographicCameraCal.from_storage([1.0, 2.0, 3.0, 4.0]) @@ -892,9 +845,7 @@ def test_lie_group_ops_OrthographicCameraCal(self): np.array([-2.3, -3.5, 0.6000000000000001, 0.20000000000000018]), ) - def test_pixel_from_camera_point_OrthographicCameraCal(self): - # type: () -> None - + def test_pixel_from_camera_point_OrthographicCameraCal(self) -> None: # NOTE(brad): The magic numbers come from the jinja template, and are the outputs # of the symbolic class's methods. diff --git a/test/cam_spherical_test.py b/test/cam_spherical_test.py index 371aaa7f4..8baac9e26 100644 --- a/test/cam_spherical_test.py +++ b/test/cam_spherical_test.py @@ -52,9 +52,7 @@ def test_max_critical_theta(self) -> None: def test_projection_valid(self) -> None: # r(theta) = theta - (1/3) * theta^3 - cal = cal = sf.SphericalCameraCal( - (1.0, 1.0), (0.0, 0.0), (-1.0 / 3, 0.0, 0.0, 0.0, 0.0, 0.0) - ) + cal = sf.SphericalCameraCal((1.0, 1.0), (0.0, 0.0), (-1.0 / 3, 0.0, 0.0, 0.0, 0.0, 0.0)) # by construction, projection should be valid for theta <= 1, invalid for theta > 1 valid_point = sf.V3(1.0, 0.0, 1.0) diff --git a/test/geo_matrix_test.py b/test/geo_matrix_test.py index 0838a87ea..6db0c3143 100644 --- a/test/geo_matrix_test.py +++ b/test/geo_matrix_test.py @@ -469,13 +469,13 @@ def test_vector_methods(self) -> None: self.assertEqual(sf.V2.unit_x().x, 1) self.assertEqual(sf.V2.unit_x().y, 0) with self.assertRaises(AttributeError): - _ = sf.V2.unit_x().z # type: ignore[attr-defined] # pylint: disable=no-member + _ = sf.V2.unit_x().z # type: ignore[attr-defined] self.assertEqual(sf.V2.unit_y().x, 0) self.assertEqual(sf.V2.unit_y().y, 1) with self.assertRaises(AttributeError): - sf.V2.unit_z() # type: ignore[attr-defined] # pylint: disable=no-member + sf.V2.unit_z() # type: ignore[attr-defined] self.assertEqual(sf.V3.unit_x().x, 1) self.assertEqual(sf.V3.unit_x().y, 0) diff --git a/test/geo_package_python_test.py b/test/geo_package_python_test.py index 0f6674eff..db70927d6 100644 --- a/test/geo_package_python_test.py +++ b/test/geo_package_python_test.py @@ -29,14 +29,12 @@ class GeoPackageTest(unittest.TestCase): since the math is tested comprehensively in symbolic form. """ - def setUp(self): - # type: () -> None + def setUp(self) -> None: np.random.seed(42) # Store verbosity flag so tests can use self.verbose = ("-v" in sys.argv) or ("--verbose" in sys.argv) - def test_storage_ops_Rot2(self): - # type: () -> None + def test_storage_ops_Rot2(self) -> None: """ Tests: sym.Rot2 StorageOps @@ -60,8 +58,7 @@ def test_storage_ops_Rot2(self): value3 = geo_class.from_storage(vec) self.assertNotEqual(value.data, value3.data) - def test_group_ops_Rot2(self): - # type: () -> None + def test_group_ops_Rot2(self) -> None: """ Tests: sym.Rot2 GroupOps @@ -83,8 +80,7 @@ def test_group_ops_Rot2(self): self.assertEqual(identity, identity.inverse()) self.assertEqual(identity, identity.between(identity)) - def test_lie_group_ops_Rot2(self): - # type: () -> None + def test_lie_group_ops_Rot2(self) -> None: """ Tests: sym.Rot2 LieGroupOps @@ -116,8 +112,7 @@ def test_lie_group_ops_Rot2(self): identity.interpolate(value, 1.0).to_storage(), value.to_storage() ) - def test_custom_methods_Rot2(self): - # type: () -> None + def test_custom_methods_Rot2(self) -> None: """ Tests: sym.Rot2 custom methods @@ -147,8 +142,7 @@ def test_custom_methods_Rot2(self): with self.assertRaises(IndexError): geo_class([1, 2, 3, 4, 5, 6]) - def test_storage_ops_Rot3(self): - # type: () -> None + def test_storage_ops_Rot3(self) -> None: """ Tests: sym.Rot3 StorageOps @@ -172,8 +166,7 @@ def test_storage_ops_Rot3(self): value3 = geo_class.from_storage(vec) self.assertNotEqual(value.data, value3.data) - def test_group_ops_Rot3(self): - # type: () -> None + def test_group_ops_Rot3(self) -> None: """ Tests: sym.Rot3 GroupOps @@ -195,8 +188,7 @@ def test_group_ops_Rot3(self): self.assertEqual(identity, identity.inverse()) self.assertEqual(identity, identity.between(identity)) - def test_lie_group_ops_Rot3(self): - # type: () -> None + def test_lie_group_ops_Rot3(self) -> None: """ Tests: sym.Rot3 LieGroupOps @@ -228,8 +220,7 @@ def test_lie_group_ops_Rot3(self): identity.interpolate(value, 1.0).to_storage(), value.to_storage() ) - def test_custom_methods_Rot3(self): - # type: () -> None + def test_custom_methods_Rot3(self) -> None: """ Tests: sym.Rot3 custom methods @@ -259,8 +250,7 @@ def test_custom_methods_Rot3(self): with self.assertRaises(IndexError): geo_class([1, 2, 3, 4, 5, 6]) - def test_storage_ops_Pose2(self): - # type: () -> None + def test_storage_ops_Pose2(self) -> None: """ Tests: sym.Pose2 StorageOps @@ -284,8 +274,7 @@ def test_storage_ops_Pose2(self): value3 = geo_class.from_storage(vec) self.assertNotEqual(value.data, value3.data) - def test_group_ops_Pose2(self): - # type: () -> None + def test_group_ops_Pose2(self) -> None: """ Tests: sym.Pose2 GroupOps @@ -307,8 +296,7 @@ def test_group_ops_Pose2(self): self.assertEqual(identity, identity.inverse()) self.assertEqual(identity, identity.between(identity)) - def test_lie_group_ops_Pose2(self): - # type: () -> None + def test_lie_group_ops_Pose2(self) -> None: """ Tests: sym.Pose2 LieGroupOps @@ -340,8 +328,7 @@ def test_lie_group_ops_Pose2(self): identity.interpolate(value, 1.0).to_storage(), value.to_storage() ) - def test_custom_methods_Pose2(self): - # type: () -> None + def test_custom_methods_Pose2(self) -> None: """ Tests: sym.Pose2 custom methods @@ -386,8 +373,7 @@ def test_custom_methods_Pose2(self): with self.assertRaises(ValueError): geo_class(R=4) # type: ignore[arg-type] - def test_storage_ops_Pose3(self): - # type: () -> None + def test_storage_ops_Pose3(self) -> None: """ Tests: sym.Pose3 StorageOps @@ -411,8 +397,7 @@ def test_storage_ops_Pose3(self): value3 = geo_class.from_storage(vec) self.assertNotEqual(value.data, value3.data) - def test_group_ops_Pose3(self): - # type: () -> None + def test_group_ops_Pose3(self) -> None: """ Tests: sym.Pose3 GroupOps @@ -434,8 +419,7 @@ def test_group_ops_Pose3(self): self.assertEqual(identity, identity.inverse()) self.assertEqual(identity, identity.between(identity)) - def test_lie_group_ops_Pose3(self): - # type: () -> None + def test_lie_group_ops_Pose3(self) -> None: """ Tests: sym.Pose3 LieGroupOps @@ -467,8 +451,7 @@ def test_lie_group_ops_Pose3(self): identity.interpolate(value, 1.0).to_storage(), value.to_storage() ) - def test_custom_methods_Pose3(self): - # type: () -> None + def test_custom_methods_Pose3(self) -> None: """ Tests: sym.Pose3 custom methods @@ -513,8 +496,7 @@ def test_custom_methods_Pose3(self): with self.assertRaises(ValueError): geo_class(R=4) # type: ignore[arg-type] - def test_storage_ops_Unit3(self): - # type: () -> None + def test_storage_ops_Unit3(self) -> None: """ Tests: sym.Unit3 StorageOps @@ -538,8 +520,7 @@ def test_storage_ops_Unit3(self): value3 = geo_class.from_storage(vec) self.assertNotEqual(value.data, value3.data) - def test_group_ops_Unit3(self): - # type: () -> None + def test_group_ops_Unit3(self) -> None: """ Tests: sym.Unit3 GroupOps @@ -561,8 +542,7 @@ def test_group_ops_Unit3(self): self.assertEqual(identity, identity.inverse()) self.assertEqual(identity, identity.between(identity)) - def test_lie_group_ops_Unit3(self): - # type: () -> None + def test_lie_group_ops_Unit3(self) -> None: """ Tests: sym.Unit3 LieGroupOps diff --git a/test/geo_rot3_test.py b/test/geo_rot3_test.py index c57882e09..1c2ed599a 100644 --- a/test/geo_rot3_test.py +++ b/test/geo_rot3_test.py @@ -226,7 +226,7 @@ def test_random(self) -> None: # Plot the sphere to show uniform distribution if logger.level == logging.DEBUG and self.verbose: import matplotlib.pyplot as plt - from mpl_toolkits.mplot3d import Axes3D # pylint: disable=unused-import + from mpl_toolkits.mplot3d import Axes3D # noqa: F401 fig = plt.figure() ax = fig.add_subplot(111, projection="3d") diff --git a/test/geo_unit3_test.py b/test/geo_unit3_test.py index 024a315d0..0ba09ca08 100644 --- a/test/geo_unit3_test.py +++ b/test/geo_unit3_test.py @@ -25,7 +25,8 @@ def setUp(self) -> None: def element(cls) -> sf.Unit3: return sf.Unit3.from_vector(sf.V3(0, 1, 0)) - def make_test_directions(self) -> T.List[sf.V3]: + @staticmethod + def make_test_directions() -> T.List[sf.V3]: """ Get a list of fixed and random directions for testing """ diff --git a/test/symforce_cc_sym_stubs_codegen_test.py b/test/symforce_cc_sym_stubs_codegen_test.py index 7d41aef64..c32bae555 100644 --- a/test/symforce_cc_sym_stubs_codegen_test.py +++ b/test/symforce_cc_sym_stubs_codegen_test.py @@ -11,7 +11,7 @@ import pybind11_stubgen # Needed so sys.modules["cc_sym"] exists -from symforce import cc_sym # pylint: disable=unused-import +from symforce import cc_sym # noqa: F401 from symforce import path_util from symforce.codegen import format_util from symforce.test_util import TestCase diff --git a/test/symforce_cc_sym_test.py b/test/symforce_cc_sym_test.py index a50eba528..2e476c110 100644 --- a/test/symforce_cc_sym_test.py +++ b/test/symforce_cc_sym_test.py @@ -35,7 +35,7 @@ class SymforceCCSymTest(TestCase): Test cc_sym. """ - def test_key(self) -> None: + def test_key(self) -> None: # noqa: PLR0915 """ Tests: cc_sym.Key @@ -128,7 +128,7 @@ def test_key(self) -> None: key_dumps = pickle.dumps(key) self.assertEqual(key, pickle.loads(key_dumps)) - def test_values(self) -> None: + def test_values(self) -> None: # noqa: PLR0915 """ Tests: cc_sym.Values @@ -153,9 +153,7 @@ def instantiate_type(tp: T.Type[T.Any]) -> T.Any: return tp.from_storage([0] * tp.storage_dim()) for tp in supported_types: - with self.subTest( - msg=f"Can set and retrieve {tp.__name__}" # pylint: disable=no-member - ): + with self.subTest(msg=f"Can set and retrieve {tp.__name__}"): values = cc_sym.Values() val: T.Any = instantiate_type(tp) values.set(cc_sym.Key("v"), val) @@ -294,9 +292,7 @@ def instantiate_type(tp: T.Type[T.Any]) -> T.Any: self.assertEqual(values.cleanup(), 1) for tp in supported_types: - with self.subTest( - msg=f"Can call set as a function of index_entry_t and {tp.__name__}" # pylint: disable=no-member - ): + with self.subTest(msg=f"Can call set as a function of index_entry_t and {tp.__name__}"): values = cc_sym.Values() a = cc_sym.Key("a") values.set(a, instantiate_type(tp)) @@ -654,7 +650,7 @@ def test_optimization_stats(self) -> None: self.compare_optimization_stats(stats, pickle.loads(pickle.dumps(stats))) ) - def test_optimizer(self) -> None: + def test_optimizer(self) -> None: # noqa: PLR0915 """ Tests: cc_sym.default_optimizer_params diff --git a/test/symforce_codegen_test.py b/test/symforce_codegen_test.py index eac965726..45970c522 100644 --- a/test/symforce_codegen_test.py +++ b/test/symforce_codegen_test.py @@ -140,7 +140,7 @@ def build_values() -> T.Tuple[Values, Values]: # ------------------------------------------------------------------------- @slow_on_sympy - def test_codegen_python(self) -> None: + def test_codegen_python(self) -> None: # noqa: PLR0914 """ Test python code generation. """ @@ -159,7 +159,7 @@ def test_codegen_python(self) -> None: # TODO(aaron): This should not be necessary, but needs to happen before the load below, or # else other tests will fail - import sym # pylint: disable=unused-import + import sym # noqa: F401 output_dir = self.make_output_dir("sf_codegen_python_test_") @@ -274,7 +274,7 @@ def matrix_order() -> sf.M23: self.assertStorageNear(matrix_order_gen(), m23) @unittest.skipIf(importlib.util.find_spec("numba") is None, "Requires numba") - def test_matrix_indexing_python(self) -> None: + def test_matrix_indexing_python(self) -> None: # noqa: PLR0915 """ Tests that matrices are indexed into correctly. """ diff --git a/test/symforce_from_rotation_matrix_test.py b/test/symforce_from_rotation_matrix_test.py index 97e3e3c43..f84f28499 100644 --- a/test/symforce_from_rotation_matrix_test.py +++ b/test/symforce_from_rotation_matrix_test.py @@ -23,7 +23,7 @@ def make_rotation_matrix() -> np.ndarray: v = np.random.randn(3) w = np.random.randn(3) - w = w - proj(w, v) + w -= proj(w, v) v /= np.linalg.norm(v) w /= np.linalg.norm(w) diff --git a/test/symforce_function_codegen_test_data/symengine/az_el_from_point.py b/test/symforce_function_codegen_test_data/symengine/az_el_from_point.py index 6c844f384..ca27b4c46 100644 --- a/test/symforce_function_codegen_test_data/symengine/az_el_from_point.py +++ b/test/symforce_function_codegen_test_data/symengine/az_el_from_point.py @@ -4,11 +4,7 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 import math import typing as T diff --git a/test/symforce_function_codegen_test_data/symengine/codegen_dataclass_in_values_test_data/python/symforce/codegen_test/codegen_dataclass_in_values_test.py b/test/symforce_function_codegen_test_data/symengine/codegen_dataclass_in_values_test_data/python/symforce/codegen_test/codegen_dataclass_in_values_test.py index e2787f23d..61fe88a5a 100644 --- a/test/symforce_function_codegen_test_data/symengine/codegen_dataclass_in_values_test_data/python/symforce/codegen_test/codegen_dataclass_in_values_test.py +++ b/test/symforce_function_codegen_test_data/symengine/codegen_dataclass_in_values_test_data/python/symforce/codegen_test/codegen_dataclass_in_values_test.py @@ -4,11 +4,7 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 import math import typing as T diff --git a/test/symforce_function_codegen_test_data/symengine/codegen_python_test_data/python/symforce/codegen_python_test/python_function.py b/test/symforce_function_codegen_test_data/symengine/codegen_python_test_data/python/symforce/codegen_python_test/python_function.py index 0fe0d140f..60c0e4e19 100644 --- a/test/symforce_function_codegen_test_data/symengine/codegen_python_test_data/python/symforce/codegen_python_test/python_function.py +++ b/test/symforce_function_codegen_test_data/symengine/codegen_python_test_data/python/symforce/codegen_python_test/python_function.py @@ -4,11 +4,7 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 import math import typing as T diff --git a/test/symforce_function_codegen_test_data/symengine/databuffer_codegen_test_data/python/symforce/buffer_test/buffer_func.py b/test/symforce_function_codegen_test_data/symengine/databuffer_codegen_test_data/python/symforce/buffer_test/buffer_func.py index d31171253..e0be300f3 100644 --- a/test/symforce_function_codegen_test_data/symengine/databuffer_codegen_test_data/python/symforce/buffer_test/buffer_func.py +++ b/test/symforce_function_codegen_test_data/symengine/databuffer_codegen_test_data/python/symforce/buffer_test/buffer_func.py @@ -4,11 +4,7 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 import math import typing as T diff --git a/test/symforce_function_codegen_test_data/symengine/numba_test_func.py b/test/symforce_function_codegen_test_data/symengine/numba_test_func.py index 4ba83a21f..b42578abd 100644 --- a/test/symforce_function_codegen_test_data/symengine/numba_test_func.py +++ b/test/symforce_function_codegen_test_data/symengine/numba_test_func.py @@ -4,11 +4,7 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 import math import typing as T @@ -37,7 +33,7 @@ def numba_test_func(x): # Total ops: 0 # Input arrays - if not (x.shape == (3, 1) or x.shape == (3,)): + if not (x.shape == (3, 1) or x.shape == (3,)): # noqa: PLR1714 raise IndexError("x is expected to have shape (3, 1) or (3,)") x = x.reshape((3, 1)) diff --git a/test/symforce_function_codegen_test_data/symengine/symforce_pytorch_codegen_test/backend_test_function.py b/test/symforce_function_codegen_test_data/symengine/symforce_pytorch_codegen_test/backend_test_function.py index b658ecb12..2ce8acb54 100644 --- a/test/symforce_function_codegen_test_data/symengine/symforce_pytorch_codegen_test/backend_test_function.py +++ b/test/symforce_function_codegen_test_data/symengine/symforce_pytorch_codegen_test/backend_test_function.py @@ -4,13 +4,9 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 -import math # pylint: disable=unused-import +import math import typing as T import torch diff --git a/test/symforce_function_codegen_test_data/symengine/symforce_pytorch_codegen_test/pytorch_func.py b/test/symforce_function_codegen_test_data/symengine/symforce_pytorch_codegen_test/pytorch_func.py index 4306371f2..cb7b9b5ee 100644 --- a/test/symforce_function_codegen_test_data/symengine/symforce_pytorch_codegen_test/pytorch_func.py +++ b/test/symforce_function_codegen_test_data/symengine/symforce_pytorch_codegen_test/pytorch_func.py @@ -4,13 +4,9 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 -import math # pylint: disable=unused-import +import math import typing as T import torch diff --git a/test/symforce_function_codegen_test_data/sympy/az_el_from_point.py b/test/symforce_function_codegen_test_data/sympy/az_el_from_point.py index d13eb7c10..347c74e20 100644 --- a/test/symforce_function_codegen_test_data/sympy/az_el_from_point.py +++ b/test/symforce_function_codegen_test_data/sympy/az_el_from_point.py @@ -4,11 +4,7 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 import math import typing as T diff --git a/test/symforce_function_codegen_test_data/sympy/codegen_dataclass_in_values_test_data/python/symforce/codegen_test/codegen_dataclass_in_values_test.py b/test/symforce_function_codegen_test_data/sympy/codegen_dataclass_in_values_test_data/python/symforce/codegen_test/codegen_dataclass_in_values_test.py index e2787f23d..61fe88a5a 100644 --- a/test/symforce_function_codegen_test_data/sympy/codegen_dataclass_in_values_test_data/python/symforce/codegen_test/codegen_dataclass_in_values_test.py +++ b/test/symforce_function_codegen_test_data/sympy/codegen_dataclass_in_values_test_data/python/symforce/codegen_test/codegen_dataclass_in_values_test.py @@ -4,11 +4,7 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 import math import typing as T diff --git a/test/symforce_function_codegen_test_data/sympy/codegen_python_test_data/python/symforce/codegen_python_test/python_function.py b/test/symforce_function_codegen_test_data/sympy/codegen_python_test_data/python/symforce/codegen_python_test/python_function.py index 0fe0d140f..60c0e4e19 100644 --- a/test/symforce_function_codegen_test_data/sympy/codegen_python_test_data/python/symforce/codegen_python_test/python_function.py +++ b/test/symforce_function_codegen_test_data/sympy/codegen_python_test_data/python/symforce/codegen_python_test/python_function.py @@ -4,11 +4,7 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 import math import typing as T diff --git a/test/symforce_function_codegen_test_data/sympy/databuffer_codegen_test_data/python/symforce/buffer_test/buffer_func.py b/test/symforce_function_codegen_test_data/sympy/databuffer_codegen_test_data/python/symforce/buffer_test/buffer_func.py index be4e723aa..14ba44946 100644 --- a/test/symforce_function_codegen_test_data/sympy/databuffer_codegen_test_data/python/symforce/buffer_test/buffer_func.py +++ b/test/symforce_function_codegen_test_data/sympy/databuffer_codegen_test_data/python/symforce/buffer_test/buffer_func.py @@ -4,11 +4,7 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 import math import typing as T diff --git a/test/symforce_function_codegen_test_data/sympy/numba_test_func.py b/test/symforce_function_codegen_test_data/sympy/numba_test_func.py index 4ba83a21f..b42578abd 100644 --- a/test/symforce_function_codegen_test_data/sympy/numba_test_func.py +++ b/test/symforce_function_codegen_test_data/sympy/numba_test_func.py @@ -4,11 +4,7 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 import math import typing as T @@ -37,7 +33,7 @@ def numba_test_func(x): # Total ops: 0 # Input arrays - if not (x.shape == (3, 1) or x.shape == (3,)): + if not (x.shape == (3, 1) or x.shape == (3,)): # noqa: PLR1714 raise IndexError("x is expected to have shape (3, 1) or (3,)") x = x.reshape((3, 1)) diff --git a/test/symforce_function_codegen_test_data/sympy/symforce_pytorch_codegen_test/backend_test_function.py b/test/symforce_function_codegen_test_data/sympy/symforce_pytorch_codegen_test/backend_test_function.py index 5945748c4..494a22666 100644 --- a/test/symforce_function_codegen_test_data/sympy/symforce_pytorch_codegen_test/backend_test_function.py +++ b/test/symforce_function_codegen_test_data/sympy/symforce_pytorch_codegen_test/backend_test_function.py @@ -4,13 +4,9 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 -import math # pylint: disable=unused-import +import math import typing as T import torch diff --git a/test/symforce_function_codegen_test_data/sympy/symforce_pytorch_codegen_test/pytorch_func.py b/test/symforce_function_codegen_test_data/sympy/symforce_pytorch_codegen_test/pytorch_func.py index 4306371f2..cb7b9b5ee 100644 --- a/test/symforce_function_codegen_test_data/sympy/symforce_pytorch_codegen_test/pytorch_func.py +++ b/test/symforce_function_codegen_test_data/sympy/symforce_pytorch_codegen_test/pytorch_func.py @@ -4,13 +4,9 @@ # Do NOT modify by hand. # ----------------------------------------------------------------------------- -# pylint: disable=useless-suppression -# pylint: disable=too-many-locals -# pylint: disable=too-many-lines -# pylint: disable=too-many-statements -# pylint: disable=unused-argument +# ruff: noqa: F401, PLR0912, PLR0913, PLR0914, PLR0915, PLR0917, RUF100 -import math # pylint: disable=unused-import +import math import typing as T import torch diff --git a/test/symforce_optimizer_test.cc b/test/symforce_optimizer_test.cc index c21e508a1..e3580601c 100644 --- a/test/symforce_optimizer_test.cc +++ b/test/symforce_optimizer_test.cc @@ -67,7 +67,6 @@ TEST_CASE("Test nonlinear convergence", "[optimizer]") { INFO("Optimized values: " << values); // Local minimum from Wolfram Alpha - // pylint: disable=line-too-long // https://www.wolframalpha.com/input/?i=z+%3D+3+-+0.5+*+sin((x+-+2)+%2F+5)+%2B+1.0+*+sin((y+%2B+2)+%2F+10.) const Eigen::Vector2d expected_gt = {9.854, -17.708}; const Eigen::Vector2d actual = {values.At('x'), values.At('y')}; diff --git a/test/symforce_py_optimizer_test.py b/test/symforce_py_optimizer_test.py index 36bb568ba..e663f6e5b 100644 --- a/test/symforce_py_optimizer_test.py +++ b/test/symforce_py_optimizer_test.py @@ -30,7 +30,7 @@ def setUp(self) -> None: super().setUp() # Clear the residual cache before each test - Factor._generated_residual_cache = ( # pylint: disable=protected-access + Factor._generated_residual_cache = ( # noqa: SLF001 GeneratedResidualCache() ) @@ -104,7 +104,7 @@ def prior_residual(x: sf.Rot3, epsilon: sf.Scalar, x_prior: sf.Rot3) -> sf.V3: # Check that the factor cache has the expected number of entries self.assertEqual( - len(Factor._generated_residual_cache), # pylint: disable=protected-access + len(Factor._generated_residual_cache), # noqa: SLF001 2, ) @@ -162,7 +162,7 @@ def between(x: T.Scalar, y: T.Scalar, b: T.Scalar) -> sf.V1: # Check that the factor cache has the expected number of entries self.assertEqual( - len(Factor._generated_residual_cache), # pylint: disable=protected-access + len(Factor._generated_residual_cache), # noqa: SLF001 2, ) diff --git a/test/symforce_sympy_overrides_test.py b/test/symforce_sympy_overrides_test.py index 916977ffd..d4559f6ae 100644 --- a/test/symforce_sympy_overrides_test.py +++ b/test/symforce_sympy_overrides_test.py @@ -55,7 +55,7 @@ def numerical_derivative( float(sf.Mod(x, y).diff(x).subs({x: nx, y: ny})), numerical_derivative( lambda _x: sf.Mod(x, y).subs( - {x: _x, y: ny} # pylint: disable=cell-var-from-loop + {x: _x, y: ny} # noqa: B023 ), nx, ), @@ -65,7 +65,7 @@ def numerical_derivative( float(sf.Mod(x, y).diff(y).subs({x: nx, y: ny})), numerical_derivative( lambda _y: sf.Mod(x, y).subs( - {x: nx, y: _y} # pylint: disable=cell-var-from-loop + {x: nx, y: _y} # noqa: B023 ), ny, ), diff --git a/test/symforce_type_helpers_test.py b/test/symforce_type_helpers_test.py index 40895d454..b5b284547 100644 --- a/test/symforce_type_helpers_test.py +++ b/test/symforce_type_helpers_test.py @@ -7,14 +7,13 @@ # Unused imports here for testing purposes import symforce.symbolic as sf -from symforce import geo # pylint: disable=unused-import -from symforce import typing as T # pylint: disable=unused-import -from symforce.cam import LinearCameraCal # pylint: disable=unused-import -from symforce.geo import Pose3 # pylint: disable=unused-import -from symforce.geo import Vector3 # pylint: disable=unused-import +from symforce import geo +from symforce.cam import LinearCameraCal +from symforce.geo import Pose3 +from symforce.geo import Vector3 from symforce.test_util import TestCase from symforce.type_helpers import deduce_input_types -from symforce.typing import Scalar # pylint: disable=unused-import +from symforce.typing import Scalar class SymforceTypeHelpersTest(TestCase): @@ -23,9 +22,6 @@ class SymforceTypeHelpersTest(TestCase): """ def test_deduce_input_types(self) -> None: - # Lots of unused arguments in here - # pylint: disable=unused-argument - # Can deduce self for bound method on geo classes assert ( inspect.signature(sf.Rot3.compose).parameters["self"].annotation diff --git a/test/symforce_values_generated_key_selection_test.py b/test/symforce_values_generated_key_selection_test.py index fd641df2a..c65b8e95d 100644 --- a/test/symforce_values_generated_key_selection_test.py +++ b/test/symforce_values_generated_key_selection_test.py @@ -8,6 +8,8 @@ from symforce.test_util import TestCase from symforce.values import generated_key_selection +# ruff: noqa: SLF001 + class SymforceValuesGeneratedKeySelectionTest(TestCase): """ @@ -19,8 +21,6 @@ def test_choices_for_name(self) -> None: Tests: generated_key_selection._choices_for_name """ - # pylint: disable=protected-access - letters_to_try, sub = generated_key_selection._choices_for_name("foo") self.assertSequenceEqual( letters_to_try, ["f", "o"] + [l for l in string.ascii_lowercase if l not in "foo"] diff --git a/third_party/skymarshal/skymarshal/templates/python_init.py.template b/third_party/skymarshal/skymarshal/templates/python_init.py.template index dfc110d4e..74077060c 100644 --- a/third_party/skymarshal/skymarshal/templates/python_init.py.template +++ b/third_party/skymarshal/skymarshal/templates/python_init.py.template @@ -1,16 +1,15 @@ # This file automatically generated by skymarshal # DO NOT MODIFY BY HAND -{% if not empty_init -%} - {%- if namespace_package %} +{% if not empty_init %} + {% if namespace_package %} # mypy: ignore_errors from pkgutil import extend_path __path__ = extend_path(__path__, __name__) - - {%- else -%} - {%- for module_name, struct_name in module_items %} + {% else %} + {% for module_name, struct_name in module_items %} from .{{ module_name }} import {{ struct_name }} - {% endfor -%} - {%- endif -%} -{%- endif %} + {% endfor %} + {% endif %} +{% endif %}