Skip to content

chore: remove dead code (unimported modules, stale copies, unused internals) - #38

Closed
iklobato wants to merge 7 commits into
devfrom
chore/remove-unimported-modules
Closed

iklobato wants to merge 7 commits into
devfrom
chore/remove-unimported-modules

Conversation

@iklobato

@iklobato iklobato commented Sep 18, 2026 •

Copy link
Copy Markdown
Owner

What

Removes code that nothing uses. The package goes from 7,516 to 5,077 lines (45 to 34 files). Behaviour does not change.

One commit per step, so each can be reverted alone:

  1. 10 modules that nothing imports: auth_service, auth_strategy, cache_handler, cache_service, crud_sync, crud_async, queryset, http_dispatcher, middleware_pipeline, route_builder.
  2. swagger.py, also unimported. docs/api-reference/swagger.md already says v2 has no built-in Swagger UI.
  3. .cursorrules: drops the FROZEN list from 2026-03-05. The files it froze got 25 commits since that date, 14 of them in lightapi.py.
  4. lightapi.py: the old copies of the request handlers (_make_collection_handler, _make_detail_handler and nine helper functions). register() has used handler_factory for a while, so these only called each other. 910 lines down to 612.
  5. Internals with no caller in cache.py, schema.py, session_manager.py, pagination.py and exceptions.py.
  6. constants.py: an unused HttpMethod enum and ten unused constants. config.py: Config.update, Authentication.permission_value and an empty __post_init__. rest.py: an attribute that was written and never read, and a try/except ImportError around sqlalchemy.Uuid that could not fail.
  7. pyproject.toml: lint and type-check entries for files that no longer exist. Project metadata is untouched.

Why

Most of this is left over from an earlier try at splitting lightapi.py into classes. The split was never wired in, and the copies drifted. For example the dead _check_auth in lightapi.py treated AllowAny differently from the live auth_checker.check_auth, so reading the main file gave the wrong rule.

How I checked each thing is dead

Not checked: code outside this repo. The removed modules imported without error before, and Config.update, Authentication.permission_value and the SessionManager methods session, async_session, dispose were public names, even if undocumented. Code that uses any of them directly would break.

Checks

All run on my machine. The test workflow does not run for PRs into dev, only GitGuardian did.

  • pytest: 327 passed, 1 xfailed, 2 xpassed. Same as dev.
  • Coverage on lightapi/: 59% on dev (3,399 statements, 1,390 missed), 82% here (2,343 and 429). Same tests, less untested code. Still under the 90% target.
  • ruff check, ruff format --check, mypy: clean.

iklo added 7 commits September 18, 2026 09:35
auth_service, auth_strategy, cache_handler, cache_service, crud_sync,
crud_async, queryset, http_dispatcher, middleware_pipeline and
route_builder are leftovers of an earlier attempt to split lightapi.py
into classes. The split was never wired: register() still builds its
handlers through handler_factory, and RestEndpoint still owns the CRUD.

No file in the package, tests, examples or docs imports any of them,
none is exported from lightapi/__init__.py, and no open PR touches
them. queryset.py was only used by the two crud_* modules. They had
already drifted from the live code, so reading them gave the wrong
picture of how a request is handled.

pyproject.toml loses only the mypy override entries that named the
deleted files.

swagger.py is also unimported but stays: .cursorrules lists it as
frozen.

Behaviour is unchanged: 327 passed, 1 xfailed, 2 xpassed, same as
before the change. ruff, ruff format and mypy are clean.
swagger.py (SwaggerGenerator plus two route functions, 323 lines) is not
imported by the package, tests, examples or docs, and no route ever
serves it. docs/api-reference/swagger.md already tells users that v2
ships no built-in Swagger UI or OpenAPI endpoint and points them to
Starlette tooling, so the module contradicted the documented behaviour.

It was kept out of the previous commit because .cursorrules lists it as
frozen. That list dates from 2026-03-05 and is dropped in the next
commit.

Tests are unchanged: 327 passed, 1 xfailed, 2 xpassed.
The list was written on 2026-03-05 for the 1-v2-full-refactor branch and
never edited again. The files it froze kept changing anyway: 14 commits
to lightapi.py since then, 4 to auth.py, 3 to cache.py. An agent that
reads the file is told not to touch code the project itself edits every
month, so the rule only blocks work and protects nothing.

Removes the section and the three inline "FROZEN" notes that repeated
it. The rest of the file is untouched.
When the request handlers moved to handler_factory.py the originals
stayed behind: LightApi._make_collection_handler, _make_detail_handler
and nine module functions (_read_body, _check_auth, the two middleware
runners, the cache helpers, _wrap_dict_response). register() has used
handler_factory.make_* since then, so the only callers of the old
functions were each other.

The copies had drifted. The dead _check_auth treated AllowAny differently
from the live auth_checker.check_auth, so anyone reading the main file
read the wrong rule.

_validate_async_dependencies stays: run() uses it and a test imports it.
Nine imports that only served the dead code go with it. The handlers doc
now names the functions that really build the routes.

Tests are unchanged: 327 passed, 1 xfailed, 2 xpassed.
Each of these is referenced only by itself or by another item in this
list. Nothing in the package, tests, examples or docs uses them, and
none is exported from lightapi/__init__.py:

- cache.py: CacheBackend, CacheManager, _cache_manager, _get_redis.
  The live cache path is RedisCacheBackend behind get_cached,
  set_cached and invalidate_cache_prefix. RedisCache and BaseCache stay:
  they are public.
- schema.py: SchemaHelper (a class that only forwarded to the four
  module functions), register_column_type with its empty registry, and
  _strip_lightapi_kwargs.
- session_manager.py: EngineProtocol, AsyncEngineProtocol, EngineType,
  LoginValidator, clear_test_registries, and the SessionManager members
  is_async, get_registry_and_metadata, session, async_session, dispose.
  CRUD code opens its own sessions, so these were never reached. The
  docstrings now say what the class really does.
- pagination.py: PaginatorProtocol and PaginatorFactory. The protocol
  described a wrap() signature that neither paginator has.
- exceptions.py: MissingHandlerImplementationError.

Tests are unchanged: 327 passed, 1 xfailed, 2 xpassed.
- constants.py: the HttpMethod enum (only the deleted http_dispatcher
  used it; the live HttpMethod is the mixin namespace in methods.py) and
  ten constants nothing reads: RESPONSE_KEY_ERROR,
  RESPONSE_KEY_ALLOWED_METHODS, RESERVED_JWT_CLAIMS, the three
  DEFAULT_RATE_LIMIT_*, CLEANUP_INTERVAL, DEFAULT_MODE, VALID_MODES and
  DEFAULT_AUTH_PATH. Checked against lightapi/, tests/, examples/ and
  docs/.
- config.py: Config.update, Authentication.permission_value, and an
  Authentication.__post_init__ whose body was `pass`. No caller, and not
  shown in any doc or example.
- rest.py: _test_isolation_table_name was written on every endpoint
  class and never read. The try/except around `from sqlalchemy import
  Uuid` could never fail: the dependency floor is SQLAlchemy 2.0.30 and
  Uuid is present there (checked on 2.0.30 and 2.0.40), so the PG_UUID
  fallback was unreachable.

Tests are unchanged: 327 passed, 1 xfailed, 2 xpassed.
pyproject.toml still carried a ruff per-file-ignore and a mypy
ignore_errors entry for base_endpoint, database, handlers and models.
Those four files were deleted in e2faf25 ("Remove legacy features and
fix documentation"), so the entries matched nothing.

Only the [tool.ruff] and [tool.mypy] tables change. ruff and mypy give
the same result as before.
@iklobato

Copy link
Copy Markdown
Owner Author

Consolidated into #44 for a single review pass (one PR covering all five refactors plus the validation work, instead of six stacked ones). Closing this one, no commits were rewritten, they're all still in #44's history.

@iklobato iklobato closed this Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant