Catalog PyPI
PACKAGE EXPLORERView in registry

adamlint

PyPI

A linter launcher for projects that have multiple source languages.

Versions collected1
Direct dependencies3From release 1.1.0
Last observed20 Oct, 19:01 UTC

README

Version 1.1.0 documentation

zulint

CI

zulint is a lightweight linting framework designed for complex applications using a mix of third-party linters and custom rules.

This project requires Python 3.10 or newer. Our CI tests run on Python 3.10–3.13 and the upcoming Python 3.14 pre-release.

Why zulint

Modern full-stack web applications generally involve code written in several programming languages, each of which have their own standard linter tools. For example, Zulip uses Python (mypy/pyflake/pycodestyle), JavaScript (eslint), CSS (stylelint), puppet (puppet-lint), shell (shellcheck), and several more. For many codebases, this results in linting being an unpleasantly slow experience, resulting in even more unpleasant secondary problems like developers merging code that doesn't pass lint, not enforcing linter rules, and debates about whether a useful linter is "worth the time".

Zulint is the linter framework we built for Zulip to create a reliable, lightning-fast linter experience to solve these problems. It has the following features:

  • Integrates with git to only checks files in source control (not automatically generated, untracked, or .gitignore files).
  • Runs the linters in parallel, so you only have to wait for the slowest linter. For Zulip, this is a ~4x performance improvement over running our third-party linters in series.
  • Produduces easy-to-read, clear terminal output, with each independent linter given its own color from a palette including orange, pink, and more.
  • Can check just modified files, or even as a pre-commit hook, only checking files that have changed (and only starting linters which check files that have changed).
  • Handles all the annoying details of flushing stdout and managing color codes.
  • Highly configurable.
    • Integrate a third-party linter with just a couple lines of code.
    • Every feature supports convenient include/exclude rules.
    • Add custom lint rules with a powerful regular expression framework. E.g. in Zulip, we want all access to Message objects in views code to be done via our access_message_by_id functions (which do security checks to ensure the user the request is being done on behalf of has access to the message), and that is enforced in part by custom regular expression lint rules. This system is optimized Python: Zulip has a few hundred custom linter rules of this type.
    • Easily add custom options to check subsets of your codebase, subsets of rules, etc.
  • Has a nice automated testing framework for custom lint rules, so you can make sure your rules actually work.

This codebase has been in production use in Zulip for several years, but only in 2019 was generalized for use by other projects. Its API to be beta and may change (with notice in the release notes) if we discover a better API, and patches to further extend it for more use cases are encouraged.

Using adamlint

Once a project is setup with zulint, you'll have a top-level linter script with at least the following options:

$ ./example-lint --help
usage: example-lint [-h] [--modified] [--verbose-timing] [--skip SKIP]
                    [--only ONLY] [--list] [--list-groups] [--groups GROUPS]
                    [--verbose] [--fix]
                    [targets [targets ...]]

positional arguments:
  targets               Specify directories to check

optional arguments:
  -h, --help            show this help message and exit
  --modified, -m        Only check modified files
  --verbose-timing, -vt
                        Print verbose timing output
  --skip SKIP           Specify linters to skip, eg: --skip=mypy,gitlint
  --only ONLY           Specify linters to run, eg: --only=mypy,gitlint
  --list, -l            List all the registered linters
  --list-groups, -lg    List all the registered linter groups
  --groups GROUPS, -g GROUPS
                        Only run linter for languages in the group(s), e.g.:
                        --groups=backend,frontend
  --verbose, -v         Print verbose output where available
  --fix                 Automatically fix problems where supported

External linters in subdirectories

When registering an external linter with linter_config.external_linter, you can now pass a cwd argument to run the linter in a different working directory. This is helpful in monorepos where individual projects maintain their own configuration files.

pre-commit hook mode

See https://github.com/adambirds/xkcd-password-gen/blob/master/tools/pre-commit for an example pre-commit hook.

Development

Run the following commands in a terminal to install zulint.

git clone git@github.com:adambirds/adamlint.git
python3 -m venv venv
source venv/bin/activate
python3 setup.py install

Downloads & popularity

19downloads
1-day window · source-reported counts19 Oct 2026
2201100
2026-07-22: 11 · observed 2026-10-20T21:32:28.3077218Z · period 2026-07-22–2026-07-222026-07-23: 2 · observed 2026-10-20T21:32:28.3077218Z · period 2026-07-23–2026-07-232026-07-24: 11 · observed 2026-10-20T21:32:28.3077218Z · period 2026-07-24–2026-07-242026-07-25: 5 · observed 2026-10-20T21:32:28.3077218Z · period 2026-07-25–2026-07-252026-07-27: 13 · observed 2026-10-20T21:32:28.3077218Z · period 2026-07-27–2026-07-272026-07-28: 11 · observed 2026-10-20T21:32:28.3077218Z · period 2026-07-28–2026-07-282026-07-29: 11 · observed 2026-10-20T21:32:28.3077218Z · period 2026-07-29–2026-07-292026-07-30: 7 · observed 2026-10-20T21:32:28.3077218Z · period 2026-07-30–2026-07-302026-07-31: 1 · observed 2026-10-20T21:32:28.3077218Z · period 2026-07-31–2026-07-312026-08-01: 8 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-01–2026-08-012026-08-02: 1 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-02–2026-08-022026-08-03: 9 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-03–2026-08-032026-08-05: 5 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-05–2026-08-052026-08-06: 4 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-06–2026-08-062026-08-07: 15 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-07–2026-08-072026-08-08: 14 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-08–2026-08-082026-08-09: 39 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-09–2026-08-092026-08-10: 12 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-10–2026-08-102026-08-11: 6 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-11–2026-08-112026-08-12: 5 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-12–2026-08-122026-08-13: 3 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-13–2026-08-132026-08-14: 5 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-14–2026-08-142026-08-15: 155 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-15–2026-08-152026-08-16: 50 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-16–2026-08-162026-08-17: 27 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-17–2026-08-172026-08-18: 61 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-18–2026-08-182026-08-19: 107 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-19–2026-08-192026-08-20: 15 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-20–2026-08-202026-08-21: 19 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-21–2026-08-212026-08-22: 21 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-22–2026-08-222026-08-23: 3 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-23–2026-08-232026-08-24: 10 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-24–2026-08-242026-08-25: 14 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-25–2026-08-252026-08-26: 28 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-26–2026-08-262026-08-27: 17 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-27–2026-08-272026-08-28: 14 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-28–2026-08-282026-08-29: 33 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-29–2026-08-292026-08-30: 4 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-30–2026-08-302026-08-31: 5 · observed 2026-10-20T21:32:28.3077218Z · period 2026-08-31–2026-08-312026-09-01: 1 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-01–2026-09-012026-09-02: 1 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-02–2026-09-022026-09-04: 6 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-04–2026-09-042026-09-05: 16 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-05–2026-09-052026-09-06: 54 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-06–2026-09-062026-09-07: 92 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-07–2026-09-072026-09-08: 78 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-08–2026-09-082026-09-09: 3 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-09–2026-09-092026-09-10: 7 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-10–2026-09-102026-09-11: 25 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-11–2026-09-112026-09-12: 24 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-12–2026-09-122026-09-13: 7 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-13–2026-09-132026-09-14: 52 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-14–2026-09-142026-09-15: 70 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-15–2026-09-152026-09-16: 59 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-16–2026-09-162026-09-17: 4 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-17–2026-09-172026-09-18: 1 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-18–2026-09-182026-09-19: 27 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-19–2026-09-192026-09-20: 23 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-20–2026-09-202026-09-21: 5 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-21–2026-09-212026-09-22: 6 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-22–2026-09-222026-09-23: 4 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-23–2026-09-232026-09-24: 3 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-24–2026-09-242026-09-25: 1 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-25–2026-09-252026-09-26: 28 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-26–2026-09-262026-09-27: 12 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-27–2026-09-272026-09-28: 12 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-28–2026-09-282026-09-29: 4 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-29–2026-09-292026-09-30: 10 · observed 2026-10-20T21:32:28.3077218Z · period 2026-09-30–2026-09-302026-10-01: 3 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-01–2026-10-012026-10-02: 3 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-02–2026-10-022026-10-03: 16 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-03–2026-10-032026-10-04: 28 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-04–2026-10-042026-10-05: 5 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-05–2026-10-052026-10-06: 18 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-06–2026-10-062026-10-07: 2 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-07–2026-10-072026-10-08: 9 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-08–2026-10-082026-10-09: 14 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-09–2026-10-092026-10-10: 14 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-10–2026-10-102026-10-11: 3 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-11–2026-10-112026-10-12: 9 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-12–2026-10-122026-10-13: 18 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-13–2026-10-132026-10-14: 29 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-14–2026-10-142026-10-15: 45 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-15–2026-10-152026-10-16: 2 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-16–2026-10-162026-10-17: 220 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-17–2026-10-172026-10-18: 120 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-18–2026-10-182026-10-19: 19 · observed 2026-10-20T21:32:28.3077218Z · period 2026-10-19–2026-10-19
22 Jul19 Oct

pypistats · 87 observations shown. Missing days are unknown. Source category: overall: without mirrors.

View observed values
Date / source periodValueObserved at
2026-10-19 – 2026-10-19192026-10-20T21:32:28.3077218Z
2026-10-18 – 2026-10-181202026-10-20T21:32:28.3077218Z
2026-10-17 – 2026-10-172202026-10-20T21:32:28.3077218Z
2026-10-16 – 2026-10-1622026-10-20T21:32:28.3077218Z
2026-10-15 – 2026-10-15452026-10-20T21:32:28.3077218Z
2026-10-14 – 2026-10-14292026-10-20T21:32:28.3077218Z
2026-10-13 – 2026-10-13182026-10-20T21:32:28.3077218Z
2026-10-12 – 2026-10-1292026-10-20T21:32:28.3077218Z
2026-10-11 – 2026-10-1132026-10-20T21:32:28.3077218Z
2026-10-10 – 2026-10-10142026-10-20T21:32:28.3077218Z
2026-10-09 – 2026-10-09142026-10-20T21:32:28.3077218Z
2026-10-08 – 2026-10-0892026-10-20T21:32:28.3077218Z
2026-10-07 – 2026-10-0722026-10-20T21:32:28.3077218Z
2026-10-06 – 2026-10-06182026-10-20T21:32:28.3077218Z
2026-10-05 – 2026-10-0552026-10-20T21:32:28.3077218Z
2026-10-04 – 2026-10-04282026-10-20T21:32:28.3077218Z
2026-10-03 – 2026-10-03162026-10-20T21:32:28.3077218Z
2026-10-02 – 2026-10-0232026-10-20T21:32:28.3077218Z
2026-10-01 – 2026-10-0132026-10-20T21:32:28.3077218Z
2026-09-30 – 2026-09-30102026-10-20T21:32:28.3077218Z
2026-09-29 – 2026-09-2942026-10-20T21:32:28.3077218Z
2026-09-28 – 2026-09-28122026-10-20T21:32:28.3077218Z
2026-09-27 – 2026-09-27122026-10-20T21:32:28.3077218Z
2026-09-26 – 2026-09-26282026-10-20T21:32:28.3077218Z
2026-09-25 – 2026-09-2512026-10-20T21:32:28.3077218Z
2026-09-24 – 2026-09-2432026-10-20T21:32:28.3077218Z
2026-09-23 – 2026-09-2342026-10-20T21:32:28.3077218Z
2026-09-22 – 2026-09-2262026-10-20T21:32:28.3077218Z
2026-09-21 – 2026-09-2152026-10-20T21:32:28.3077218Z
2026-09-20 – 2026-09-20232026-10-20T21:32:28.3077218Z
2026-09-19 – 2026-09-19272026-10-20T21:32:28.3077218Z
2026-09-18 – 2026-09-1812026-10-20T21:32:28.3077218Z
2026-09-17 – 2026-09-1742026-10-20T21:32:28.3077218Z
2026-09-16 – 2026-09-16592026-10-20T21:32:28.3077218Z
2026-09-15 – 2026-09-15702026-10-20T21:32:28.3077218Z
2026-09-14 – 2026-09-14522026-10-20T21:32:28.3077218Z
2026-09-13 – 2026-09-1372026-10-20T21:32:28.3077218Z
2026-09-12 – 2026-09-12242026-10-20T21:32:28.3077218Z
2026-09-11 – 2026-09-11252026-10-20T21:32:28.3077218Z
2026-09-10 – 2026-09-1072026-10-20T21:32:28.3077218Z
2026-09-09 – 2026-09-0932026-10-20T21:32:28.3077218Z
2026-09-08 – 2026-09-08782026-10-20T21:32:28.3077218Z
2026-09-07 – 2026-09-07922026-10-20T21:32:28.3077218Z
2026-09-06 – 2026-09-06542026-10-20T21:32:28.3077218Z
2026-09-05 – 2026-09-05162026-10-20T21:32:28.3077218Z
2026-09-04 – 2026-09-0462026-10-20T21:32:28.3077218Z
2026-09-02 – 2026-09-0212026-10-20T21:32:28.3077218Z
2026-09-01 – 2026-09-0112026-10-20T21:32:28.3077218Z
2026-08-31 – 2026-08-3152026-10-20T21:32:28.3077218Z
2026-08-30 – 2026-08-3042026-10-20T21:32:28.3077218Z
2026-08-29 – 2026-08-29332026-10-20T21:32:28.3077218Z
2026-08-28 – 2026-08-28142026-10-20T21:32:28.3077218Z
2026-08-27 – 2026-08-27172026-10-20T21:32:28.3077218Z
2026-08-26 – 2026-08-26282026-10-20T21:32:28.3077218Z
2026-08-25 – 2026-08-25142026-10-20T21:32:28.3077218Z
2026-08-24 – 2026-08-24102026-10-20T21:32:28.3077218Z
2026-08-23 – 2026-08-2332026-10-20T21:32:28.3077218Z
2026-08-22 – 2026-08-22212026-10-20T21:32:28.3077218Z
2026-08-21 – 2026-08-21192026-10-20T21:32:28.3077218Z
2026-08-20 – 2026-08-20152026-10-20T21:32:28.3077218Z
2026-08-19 – 2026-08-191072026-10-20T21:32:28.3077218Z
2026-08-18 – 2026-08-18612026-10-20T21:32:28.3077218Z
2026-08-17 – 2026-08-17272026-10-20T21:32:28.3077218Z
2026-08-16 – 2026-08-16502026-10-20T21:32:28.3077218Z
2026-08-15 – 2026-08-151552026-10-20T21:32:28.3077218Z
2026-08-14 – 2026-08-1452026-10-20T21:32:28.3077218Z
2026-08-13 – 2026-08-1332026-10-20T21:32:28.3077218Z
2026-08-12 – 2026-08-1252026-10-20T21:32:28.3077218Z
2026-08-11 – 2026-08-1162026-10-20T21:32:28.3077218Z
2026-08-10 – 2026-08-10122026-10-20T21:32:28.3077218Z
2026-08-09 – 2026-08-09392026-10-20T21:32:28.3077218Z
2026-08-08 – 2026-08-08142026-10-20T21:32:28.3077218Z
2026-08-07 – 2026-08-07152026-10-20T21:32:28.3077218Z
2026-08-06 – 2026-08-0642026-10-20T21:32:28.3077218Z
2026-08-05 – 2026-08-0552026-10-20T21:32:28.3077218Z
2026-08-03 – 2026-08-0392026-10-20T21:32:28.3077218Z
2026-08-02 – 2026-08-0212026-10-20T21:32:28.3077218Z
2026-08-01 – 2026-08-0182026-10-20T21:32:28.3077218Z
2026-07-31 – 2026-07-3112026-10-20T21:32:28.3077218Z
2026-07-30 – 2026-07-3072026-10-20T21:32:28.3077218Z
2026-07-29 – 2026-07-29112026-10-20T21:32:28.3077218Z
2026-07-28 – 2026-07-28112026-10-20T21:32:28.3077218Z
2026-07-27 – 2026-07-27132026-10-20T21:32:28.3077218Z
2026-07-25 – 2026-07-2552026-10-20T21:32:28.3077218Z
2026-07-24 – 2026-07-24112026-10-20T21:32:28.3077218Z
2026-07-23 – 2026-07-2322026-10-20T21:32:28.3077218Z
2026-07-22 – 2026-07-22112026-10-20T21:32:28.3077218Z

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
1.1.030 Aug 20253

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
adambirds/adamlint

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 19:01 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:24be04b2b29a77ca50f076ab049b88cabde261a7b21faa6dcec11880dbc509f6