PEP-484 typing stubs for SQLAlchemy 1.4 and SQLAlchemy 2.0

Overview

SQLAlchemy 2 Stubs

These are PEP-484 typing stubs for SQLAlchemy 1.4 and 2.0. They are released concurrently along with a Mypy extension which is designed to work with these stubs, which assists primarily in the area of ORM mappings.

The stubs replace the use of the "sqlalchemy-stubs" package published by Dropbox. Differences include that these stubs are generated against 1.4's API as well as some adjustments to the use of generics.

This project should be considered alpha level and is not as mature as the Dropbox stubs for the initial release.

See the Mypy plugin documentation at https://docs.sqlalchemy.org/en/14/orm/extensions/mypy.html for an overview of how to use PEP-484 annotations with ORM mapped classes.

Code of Conduct

Above all, SQLAlchemy places great emphasis on polite, thoughtful, and constructive communication between users and developers. Please see our current Code of Conduct at Code of Conduct.

License

SQLAlchemy is distributed under the MIT license.

Comments
  • 'DeclarativeMeta' is not defined

    'DeclarativeMeta' is not defined

    Describe your question When creating a Base class with @as_declarative the following errors shows up using mypy error: Name 'DeclarativeMeta' is not defined. Am I doing something wrong or is there a better way?

    Example - please use the Minimal, Complete, and Verifiable guidelines if possible Using the example as provided in the documentation, it works without a problem:

    Base = declarative_base()
    
    class User(Base):
        __tablename__ = 'user'
    
        id = Column(Integer, primary_key=True)
        name = Column(String)
    
        addresses: Mapped[List["Address"]] = relationship("Address", back_populates="user")
    
    class Address(Base):
        __tablename__ = 'address'
    
        id = Column(Integer, primary_key=True)
        user_id: int = Column(ForeignKey("user.id"))
    
        user: Mapped[User] = relationship(User, back_populates="addresses")
    
    main  mypy --config mypy.ini --strict simple-test.py
    Success: no issues found in 1 source file
    

    When trying to use it as following it shows the error:

    @as_declarative()
    class Base(object):
        id = Column(Integer, primary_key=True)
    
    
    class User(Base):
        __tablename__ = "user"
    
        name = Column(String)
    
        addresses: Mapped[List["Address"]] = relationship("Address", back_populates="user")
    
    
    class Address(Base):
        __tablename__ = "address"
    
        user_id: int = Column(ForeignKey("user.id"))
    
        user: Mapped[User] = relationship(User, back_populates="addresses")
    
    main  mypy --config mypy.ini --strict simple-test.py
    simple-test.py: error: Name 'DeclarativeMeta' is not defined
    

    mypy config

    [mypy]
    plugins = sqlalchemy.ext.mypy.plugin
    

    Versions

    • OS: MacOS 11.0
    • Python: Python 3.9.2
    • Mypy: mypy 0.812
    • SQLAlchemy: 1.4.3
    • sqlalchemy2-stub: 0.0.1a4
    • Database: n/a
    • DBAPI: n/a
    bug 
    opened by blokje 22
  • Fix formatting

    Fix formatting

    Description

    Updates code style and pre-commit checks to match sqlalchemy. A few things to note:

    • # fmt: off + # fmt: on was needed to keep black and zimports from fighting
    • I added flake8-pyi and did not include flake8-builtins, flake8-docstrings, and flake8-rst-docstrings because they are irrelevant for pyi files

    Checklist

    This pull request is:

    • [ ] A documentation / typographical error fix
      • Good to go, no issue or tests are needed
    • [x] A short code fix
      • please include the issue number, and create an issue if none exists, which must include a complete example of the issue. one line code fixes without an issue and demonstration will not be accepted.
      • Please include: Fixes: #<issue number> in the commit message
      • please include tests. one line code fixes without tests will not be accepted.
    • [ ] A new feature implementation
      • please include the issue number, and create an issue if none exists, which must include a complete example of how the feature would look.
      • Please include: Fixes: #<issue number> in the commit message
      • please include tests.

    Have a nice day!

    opened by bryanforbes 15
  • Asynchronous sessionmaker initialization type error

    Asynchronous sessionmaker initialization type error

    Describe the bug mypy fails on asynchronous sessionmaker initialization.

    Expected behavior No errors.

    To Reproduce Please try to provide a Minimal, Complete, and Verifiable example. See also Reporting Bugs on the website, and some example issues.

    Please do not use Flask-SQLAlchemy or any other third-party extensions or dependencies in test cases. The test case must illustrate the problem without using any third party SQLAlchemy extensions. Otherwise, please report the bug to those projects first.

    import os
    
    from sqlalchemy.ext.asyncio import AsyncSession
    from sqlalchemy.ext.asyncio import create_async_engine
    from sqlalchemy.orm import sessionmaker
    
    engine = create_async_engine(os.getenv("DATABASE_URL"))
    async_session = sessionmaker(engine, class_=AsyncSession)
    

    Error

    session.py:8: error: Value of type variable "_TSessionMakerType" of "sessionmaker" cannot be "AsyncSession"
    Found 1 error in 1 file (checked 1 source file)
    

    Versions.

    • OS: Linux
    • Python: 3.9.6
    • SQLAlchemy: 1.4.23
    • mypy: 0.910
    • SQLAlchemy2-stubs: v0.0.2a9

    Additional context The problem appeared on the latest release of sqlalchemy2-stubs and was not present on v0.0.2a8.

    Have a nice day!

    bug 
    opened by r4rdsn 13
  • relationship types not detected when passing related class as str

    relationship types not detected when passing related class as str

    I was just trying out the new stubs on an existing project if mine, and it looks like you did some awesome work there - I can get rid of a lot of workarounds. Thanks! Nevertheless, there's one issue I wanted to share with you.

    Describe the bug There are two ways to pass the first parameter of a relationship: by class or by str. When using the class directly everything works as expected, the type is detected when using uselist or relationsship. And I don't find any false positives afterwards.

    When I use a str to configure my relationship things get pretty messy. First, I need to type the annotations manually, I wasn't able to find any way to configure it such that auto-detection works.

    [SQLAlchemy Mypy plugin] Can't infer type from ORM mapped expression assigned to attribute 'addresses'; please specify a Python type or Mapped[<python type>] on the left hand side.
    

    Second, even when annotating it manually, I'll have to cast it every single time I use it (when it's some kind of Iterable as shown in the example below).

    error: "List?[Address?]" has no attribute "__iter__" (not iterable)
    error: "List?[Address?]" has no attribute "append"
    

    Expected behavior Type detection works for relationship independent of type of first argument.

    To Reproduce

    from __future__ import annotations
    
    from typing import List
    
    from sqlalchemy import Integer, Column, String, ForeignKey
    from sqlalchemy.orm import declarative_base, relationship
    
    Base = declarative_base()
    
    
    class User(Base):
    
        __tablename__ = "users"
    
        id = Column(Integer, primary_key=True)
        name = Column(String)
    
        addresses: List[Address] = relationship("Address", back_populates="user", uselist=True)
    
        def clone(self) -> User:
            new_user = User(name=self.name)
    
            for existing_addr in self.addresses:
                new_user.addresses.append(
                    Address(address=existing_addr.address)
                )
            return new_user
    
    
    class Address(Base):
    
        __tablename__ = "addresses"
    
        id = Column(Integer, primary_key=True)
        address = Column(String)
        
        user_id = Column(Integer, ForeignKey("users.id"))
        
        user = relationship(User, back_populates="addresses", uselist=False)
    
    

    Versions.

    • OS: WIn10
    • Python: 3.8.6
    • SQLAlchemy: 1.4.9
    • Database:
    • DBAPI:

    Have a nice day! You too ;)

    bug duplicate 
    opened by TilmanK 11
  • don't use typing with ServerDefaultType

    don't use typing with ServerDefaultType

    The server default is any expression that is passed as DDL to the database and these usually don't have SQL types explicitly stated.

    With the code as is, pylance is complaining about this:

    Column(DateTime(), server_default=func.now())
    

    and requiring I do this:

    Column(DateTime(), server_default=func.now(type_=DateTime))
    

    people don't need to do that, server_defaults SQL type always comes from the column type and doesn't normally need to be stated.

    Also, column_server_default.py was importing "functions as func", which is wrong. "func" is not a module it's a namespace object, fixed that.

    opened by zzzeek 8
  • Cannot unpack Row instance

    Cannot unpack Row instance

    Describe the bug mypy is complaining about unpacking Row object, even though it works.

    To Reproduce

    test_table = Table(
        "test_table",
        metadata,
        Column("i", UUID(as_uuid=True), nullable=False, primary_key=True),
        Column("x", UUID(as_uuid=True), index=True),
        Column("y", UUID(as_uuid=True), index=True),
    )
    query = test_table.select()
    async with engine.connect() as connection:
      result = await connection.execute(query)
    row = result.fetchone()
    if row:
      my_dict = {**row}
    

    Error

    Argument after ** must be a mapping, not "Row"
    

    Versions.

    • OS: Linux Mint 19.3 Cinnamon
    • Python: 3.7.10
    • SQLAlchemy: 1.4.15
    • Database: PostgreSQL
    • DBAPI: asyncpg
    mypy expected behavior 
    opened by mdczaplicki 8
  • Improve `orm.session`

    Improve `orm.session`

    Description

    Improve orm.session. Depends on #46. This is a large one because of _SessionProtocol and _AsyncSessionProtocol. These are needed to allow sessionmaker() to take classes that aren't required to inherit from Session or AsyncSession, but are duck-typed to be like Session or AsyncSession.

    Fixes #17.

    Checklist

    This pull request is:

    • [ ] A documentation / typographical error fix
      • Good to go, no issue or tests are needed
    • [X] A short code fix
      • please include the issue number, and create an issue if none exists, which must include a complete example of the issue. one line code fixes without an issue and demonstration will not be accepted.
      • Please include: Fixes: #<issue number> in the commit message
      • please include tests. one line code fixes without tests will not be accepted.
    • [ ] A new feature implementation
      • please include the issue number, and create an issue if none exists, which must include a complete example of how the feature would look.
      • Please include: Fixes: #<issue number> in the commit message
      • please include tests.

    Have a nice day!

    opened by bryanforbes 6
  • implement support to intercept as_declarative()

    implement support to intercept as_declarative()

    I installed the the type stubs and configured the mypy plugin as directed in the documentation

    My database is defined like this:

    @as_declarative()
    class Base:
        def __repr__(self):
            name = self.__class__.__name__
            attrs = (
                "%s=%r" % (attr, getattr(self, attr))
                for attr in self._sa_class_manager.keys()
                if not (attr[-2:] == "id" or isinstance(getattr(self, attr), list))
            )
            return name + "(%s)" % ", ".join(attrs)
    
    
    class Source(Base):
        __tablename__ = "sources"
        id = sa.Column(sa.Integer, primary_key=True)
        address = sa.Column(sa.String, index=True)
        match_id = sa.Column(sa.Integer, sa.ForeignKey("matches.id"))
    
        match = relationship("Match", back_populates="sources")
    
    
    class Match(Base):
        __tablename__ = "matches"
        id = sa.Column(sa.Integer, primary_key=True)
        original_id = sa.Column(sa.Integer, sa.ForeignKey("original.id"))
        romanized_id = sa.Column(sa.Integer, sa.ForeignKey("romanized.id"))
        count = sa.Column(sa.Integer)
    
        original = relationship("Original", back_populates="matches")
        romanized = relationship("Romanized", back_populates="matches")
        sources = relationship("Source", back_populates="match")
    
    
    sa.Index("matches_idx", Match.original_id, Match.romanized_id, unique=True)
    
    
    class Standard(Base):
        __tablename__ = "standards"
        id = sa.Column(sa.Integer, primary_key=True)
        st = sa.Column(sa.String, index=True, unique=True)
    
    
    class Original(Base):
        __tablename__ = "original"
        id = sa.Column(sa.Integer, primary_key=True)
        form = sa.Column(sa.String, index=True, unique=True)
    
        matches = relationship("Match", back_populates="original")
    
    
    class Romanized(Base):
        __tablename__ = "romanized"
        id = sa.Column(sa.Integer, primary_key=True)
        form = sa.Column(sa.String, index=True)
        standard_id = sa.Column(sa.Integer, sa.ForeignKey("standards.id"))
    
        standard = relationship(Standard)
        matches = relationship("Match", back_populates="romanized")
    
    
    sa.Index("standard_form", Romanized.form, Romanized.standard_id, unique=True)
    

    When I run mypy, I get these errors:

    $ mypy deromanize 
    deromanize/cacheutils.py:201: error: Need type annotation for 'match'
    deromanize/cacheutils.py:211: error: Need type annotation for 'original'
    deromanize/cacheutils.py:212: error: Need type annotation for 'romanized'
    deromanize/cacheutils.py:213: error: Need type annotation for 'sources'
    deromanize/cacheutils.py:230: error: Need type annotation for 'matches'
    deromanize/cacheutils.py:239: error: Need type annotation for 'standard'
    deromanize/cacheutils.py:240: error: Need type annotation for 'matches'
    Found 7 errors in 1 file (checked 6 source files)
    

    This does not match the documented error message:

    test3.py:22: error: [SQLAlchemy Mypy plugin] Can't infer scalar or
    collection for ORM mapped expression assigned to attribute 'user'
    if both 'uselist' and 'collection_class' arguments are absent from the
    relationship(); please specify a type annotation on the left hand side.
    Found 1 error in 1 file (checked 1 source file)
    

    Furthermore, when I attempt to add annotations, that doesn't work either:

    class Source(Base):
        __tablename__ = "sources"
        id = sa.Column(sa.Integer, primary_key=True)
        address = sa.Column(sa.String, index=True)
        match_id = sa.Column(sa.Integer, sa.ForeignKey("matches.id"))
    
        match: 'Match' = relationship("Match", back_populates="sources")
    
    deromanize/cacheutils.py:201: error: Incompatible types in assignment (expression has type "RelationshipProperty[<nothing>]", variable has type "Match")
    

    Am I doing something wrong or is this a bug?

    bug 
    opened by ninjaaron 6
  • on_conflict_do_update and on_conflict_do_nothing returns None it typing, but actually returns 'Insert'

    on_conflict_do_update and on_conflict_do_nothing returns None it typing, but actually returns 'Insert'

    Describe the bug Using on_conflict_do_update method with returning and PyCharm highlight return with "Cannot find reference 'returning' in 'None'"

    Expected behavior Don't see any highlight.

    To Reproduce Install packages, and try to use

    insert(self.table).on_conflict_do_update(
          index_elements=(self.table.c.id,),
          set_={
              'count': self.table.c.count + insert_query.excluded.count,
          },
      ).returning(self.table.c.id)
    

    Error

    "Cannot find reference 'returning' in 'None'"
    

    Proposition Change:

    def on_conflict_do_update(
            self,
            constraint: Optional[Any] = ...,
            index_elements: Optional[Any] = ...,
            index_where: Optional[Any] = ...,
            set_: Optional[Any] = ...,
            where: Optional[Any] = ...,
        ) -> 'Insert': ...
        def on_conflict_do_nothing(
            self,
            constraint: Optional[Any] = ...,
            index_elements: Optional[Any] = ...,
            index_where: Optional[Any] = ...,
        ) -> 'Insert': ...
    

    Versions.

    • OS: Ubuntu 20.4
    • IDE: PyCharm Professional 2022.1
    • Python: 3.8
    • SQLAlchemy: 1.4.32
    • mypy: 0.782
    • SQLAlchemy2-stubs: 0.0.2a21

    Have a nice day!

    bug missing type 
    opened by BlackLIonz 5
  • Cannot execute DDL construct

    Cannot execute DDL construct

    Describe the bug If I use a DDL construct, mypy conplains that it can't be executed. However using .execute raises a deprecation warning:

    testscript.py:9: RemovedIn20Warning: The DDLElement.execute() method is considered legacy as of the 1.x series of SQLAlchemy and will be removed in 2.0. All statement execution in SQLAlchemy 2.0 is performed by the Connection.execute() method of Connection, or in the ORM by the Session.execute() method of Session. (Background on SQLAlchemy 2.0 at: https://sqlalche.me/e/b8d9)
    

    Expected behavior Mypy doesn't complain

    To Reproduce

    from sqlalchemy.schema import CreateSequence, Sequence
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy import create_engine
    
    engine = create_engine("sqlite:////:memory:")
    session = sessionmaker(bind=engine)()
    
    construct = CreateSequence(Sequence("foo"))
    try:
        construct.execute(bind=session)  # warning
        session.execute(construct)  # mypy
    except:
        pass
    

    Error

    testscript.py:10: error: Argument "bind" to "execute" of "DDLElement" has incompatible type "Session"; expected "Union[Engine, Connection, None]"
    

    Versions.

    • OS: Linux
    • Python: 3.7.1
    • SQLAlchemy: 1.4.27
    • mypy: 0.910
    • SQLAlchemy2-stubs: 0.0.2a19

    Have a nice day!

    opened by kasium 5
  • Improve stubs of classes that have some method copied by create_proxy_methods

    Improve stubs of classes that have some method copied by create_proxy_methods

    In most cases a type only superclass can avoid repeating the definitions in one or more classes.

    Examples: Session|ScopedSession|AsyncSession; Connection|AsyncConnection

    bug enhancement 
    opened by CaselIT 5
  •  Incomplete typing for Engine.dispose's close parameter

    Incomplete typing for Engine.dispose's close parameter

    Describe the bug SQLAlchemy release 1.4.33 added a new optional close: bool = True parameter to Engine#dispose(). This is not declared in the type definition, at https://github.com/sqlalchemy/sqlalchemy2-stubs/blob/dd0e6cf7e1c61cc1c25cd1d8d72c9f322fa73d90/sqlalchemy-stubs/engine/base.pyi#L200

    Expected behavior The current type definition should declare the close parameter.

    To Reproduce Call Engine.dispose(close) and then run mypy on it with sqlalchemy2-stubs.

    engine.dispose(close=False)
    

    Error

    error: Too many arguments for "dispose" of "Engine"
    

    Versions.

    • OS: Darwin Kernel Version 21.6.0
    • Python: 3.7.10
    • SQLAlchemy: 1.4.39
    • mypy: 0.931
    • SQLAlchemy2-stubs: 0.0.2a29
    bug help wanted 
    opened by satyanash 1
  • Invalid base class

    Invalid base class "Base" when returned by a function

    Describe the bug mypy returns [Invald ](error: Invalid base class "Base" [misc]) when Base class is returned by a function.

    To Reproduce

    pip install sqlalchemy[mypy]==1.4.44
    mypy --config-file=mypy.ini test.py
    

    mypy.ini

    [mypy]
    plugins = sqlalchemy.ext.mypy.plugin
    

    test.py

    from sqlalchemy import String, select
    from sqlalchemy.orm import declarative_base
    from typing import Optional, Dict, Type
    import sqlalchemy
    from sqlalchemy.orm.ext import DeclarativeMeta
    
    def get_base() -> Type[DeclarativeMeta]:
        return declarative_base()
    
    Base: Type[DeclarativeMeta] = get_base()
    
    class User(Base):
        __tablename__ = "user"
    
        id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
        name = sqlalchemy.Column(sqlalchemy.String)
    
    

    Error

    error: Invalid base class "Base"
    

    Versions.

    • OS: Ubuntu 22.04
    • Python: 3.8
    • SQLAlchemy: 1.4.44
    • mypy: 0.991
    • SQLAlchemy2-stubs: 0.0.2a29

    Have a nice day!

    bug expected behavior 
    opened by iskyd 6
  • Type error when attempting to use a Literal[True] with sa.and_()

    Type error when attempting to use a Literal[True] with sa.and_()

    Relevant block of code:

    sa.and_(
        tb.c.VERSION == version,
        tb.c.ISIN.in_(isins) if isins is not None else True,
        tb.c.ISIN != None,  # pylint: disable=singleton-comparison
         b.c.DATE.in_(dates))
    )
    

    Error I get from pyright is:

    error: Argument of type "ColumnElement[Boolean] | Literal[True]" cannot be assigned to parameter "clauses" of type "[email protected]" in function "and_"
        Type "ColumnElement[Boolean] | Literal[True]" cannot be assigned to type "ColumnElement[Boolean]"
          "Literal[True]" is incompatible with "ColumnElement[Boolean]" (reportGeneralTypeIssues)
    
    bug 
    opened by gandhis1 1
  • Using compiles leads to untyped decorator

    Using compiles leads to untyped decorator

    Describe the bug The compile decorator is not fully typed. Therefore mypy complains when using it

    Expected behavior Mypy doesn't complain

    To Reproduce Use compile as a decorator

    Error

    error: Untyped decorator makes function "foo" untyped  [misc]
    

    Versions.

    • OS: Linux
    • Python: 3.7.1
    • SQLAlchemy: 1.4.41
    • mypy: 0.982
    • SQLAlchemy2-stubs: 0.0.2a29

    I'm happy to give a PR a try

    bug missing type 
    opened by kasium 0
  • Make Column and relationship inherit from Mapped

    Make Column and relationship inherit from Mapped

    Is your feature request related to a problem? Please describe.

    A typical typed SQLAlchemy model looks like this:

    class Model(Base):
        name: Mapped[str] = Column(Unicode(100), nullable=True)
    

    This works fine with mypy, but triggers the following error with Pylance/Pyright

    Expression of type "Column[Unicode]" cannot be assigned to declared type "Mapped[str]"
    

    Same for relationship

    Describe the solution you'd like

    Make Column and relationship inherit from Mapped

    Additional context

    I can make a PR if you're okay with this.

    Have a nice day!

    bug missing type 
    opened by mehdigmira 5
Releases(v0.0.2a31)
Owner
SQLAlchemy
The Database Toolkit and Object Relational Mapper
SQLAlchemy
Check for python builtins being used as variables or parameters

Flake8 Builtins plugin Check for python builtins being used as variables or parameters. Imagine some code like this: def max_values(list, list2):

Gil Forcada Codinachs 98 Jan 08, 2023
flake8 plugin that integrates isort

Flake8 meet isort Use isort to check if the imports on your python files are sorted the way you expect. Add an .isort.cfg to define how you want your

Gil Forcada Codinachs 139 Nov 08, 2022
A static type analyzer for Python code

pytype - 🦆 ✔ Pytype checks and infers types for your Python code - without requiring type annotations. Pytype can: Lint plain Python code, flagging c

Google 4k Dec 31, 2022
A plugin for Flake8 that provides specializations for type hinting stub files

flake8-pyi A plugin for Flake8 that provides specializations for type hinting stub files, especially interesting for linting typeshed. Functionality A

Łukasz Langa 58 Jan 04, 2023
mypy plugin to type check Kubernetes resources

kubernetes-typed mypy plugin to dynamically define types for Kubernetes objects. Features Type checking for Custom Resources Type checking forkubernet

Artem Yarmoliuk 16 Oct 10, 2022
Code audit tool for python.

Pylama Code audit tool for Python and JavaScript. Pylama wraps these tools: pycodestyle (formerly pep8) © 2012-2013, Florent Xicluna; pydocstyle (form

Kirill Klenov 967 Jan 07, 2023
Optional static typing for Python 3 and 2 (PEP 484)

Mypy: Optional Static Typing for Python Got a question? Join us on Gitter! We don't have a mailing list; but we are always happy to answer questions o

Python 14.4k Jan 08, 2023
Flake8 plugin for managing type-checking imports & forward references

flake8-type-checking Lets you know which imports to put in type-checking blocks. For the imports you've already defined inside type-checking blocks, i

snok 67 Dec 16, 2022
Custom Python linting through AST expressions

bellybutton bellybutton is a customizable, easy-to-configure linting engine for Python. What is this good for? Tools like pylint and flake8 provide, o

H. Chase Stevens 249 Dec 31, 2022
Utilities for refactoring imports in python-like syntax.

aspy.refactor_imports Utilities for refactoring imports in python-like syntax. Installation pip install aspy.refactor_imports Examples aspy.refactor_i

Anthony Sottile 20 Nov 01, 2022
A simple program which checks Python source files for errors

Pyflakes A simple program which checks Python source files for errors. Pyflakes analyzes programs and detects various errors. It works by parsing the

Python Code Quality Authority 1.2k Dec 30, 2022
Utilities for pycharm code formatting (flake8 and black)

Pycharm External Tools Extentions to Pycharm code formatting tools. Currently supported are flake8 and black on a selected code block. Usage Flake8 [P

Haim Daniel 13 Nov 03, 2022
Pymxs, the 3DsMax bindings of Maxscript to Python doesn't come with any stubs

PyMXS Stubs generator What Pymxs, the 3DsMax bindings of Maxscript to Python doe

Frieder Erdmann 19 Dec 27, 2022
A static-analysis bot for Github

Imhotep, the peaceful builder. What is it? Imhotep is a tool which will comment on commits coming into your repository and check for syntactic errors

Justin Abrahms 221 Nov 10, 2022
Run isort, pyupgrade, mypy, pylint, flake8, and more on Jupyter Notebooks

Run isort, pyupgrade, mypy, pylint, flake8, mdformat, black, blacken-docs, and more on Jupyter Notebooks ✅ handles IPython magics robustly ✅ respects

663 Jan 08, 2023
A plugin for Flake8 that checks pandas code

pandas-vet pandas-vet is a plugin for flake8 that provides opinionated linting for pandas code. It began as a project during the PyCascades 2019 sprin

Jacob Deppen 146 Dec 28, 2022
mypy plugin for loguru

loguru-mypy A fancy plugin to boost up your logging with loguru mypy compatibility logoru-mypy should be compatible with mypy=0.770. Currently there

Tomasz Trębski 13 Nov 02, 2022
open source tools to generate mypy stubs from protobufs

mypy-protobuf: Generate mypy stub files from protobuf specs We just released a new major release mypy-protobuf 2. on 02/02/2021! It includes some back

Dropbox 527 Jan 03, 2023
docstring style checker

pydocstyle - docstring style checker pydocstyle is a static analysis tool for checking compliance with Python docstring conventions. pydocstyle suppor

Python Code Quality Authority 982 Jan 03, 2023
Unbearably fast O(1) runtime type-checking in pure Python.

Look for the bare necessities, the simple bare necessities. Forget about your worries and your strife. — The Jungle Book.

beartype 1.4k Jan 01, 2023