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
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
A plugin for flake8 integrating Mypy.

flake8-mypy NOTE: THIS PROJECT IS DEAD It was created in early 2017 when Mypy performance was often insufficient for in-editor linting. The Flake8 plu

Łukasz Langa 103 Jun 23, 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
OpenStack Hacking Style Checks. Mirror of code maintained at opendev.org.

Introduction hacking is a set of flake8 plugins that test and enforce the OpenStack StyleGuide Hacking pins its dependencies, as a new release of some

Mirrors of opendev.org/openstack 224 Jan 05, 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
PEP-484 typing stubs for SQLAlchemy 1.4 and SQLAlchemy 2.0

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 desi

SQLAlchemy 139 Dec 30, 2022
❄️ A flake8 plugin to help you write better list/set/dict comprehensions.

flake8-comprehensions A flake8 plugin that helps you write better list/set/dict comprehensions. Requirements Python 3.6 to 3.9 supported. Installation

Adam Johnson 398 Dec 23, 2022
Flake8 wrapper to make it nice, legacy-friendly, configurable.

THE PROJECT IS ARCHIVED Forks: https://github.com/orsinium/forks It's a Flake8 wrapper to make it cool. Lint md, rst, ipynb, and more. Shareable and r

Life4 232 Dec 16, 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
flake8 plugin to run black for checking Python coding style

flake8-black Introduction This is an MIT licensed flake8 plugin for validating Python code style with the command line code formatting tool black. It

Peter Cock 146 Dec 15, 2022
flake8 plugin to catch useless `assert` statements

flake8-useless-assert flake8 plugin to catch useless assert statements Download or install on the PyPI page Violations Code Description Example ULA001

1 Feb 12, 2022
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
Type stubs for the lxml package

lxml-stubs About This repository contains external type annotations (see PEP 484) for the lxml package. Installation To use these stubs with mypy, you

25 Dec 26, 2022
Pylint plugin for improving code analysis for when using Django

pylint-django About pylint-django is a Pylint plugin for improving code analysis when analysing code using Django. It is also used by the Prospector t

Python Code Quality Authority 544 Jan 06, 2023
The official GitHub mirror of https://gitlab.com/pycqa/flake8

Flake8 Flake8 is a wrapper around these tools: PyFlakes pycodestyle Ned Batchelder's McCabe script Flake8 runs all the tools by launching the single f

Python Code Quality Authority 2.6k Jan 03, 2023
Flake8 Type Annotation Checking

flake8-annotations flake8-annotations is a plugin for Flake8 that detects the absence of PEP 3107-style function annotations and PEP 484-style type co

S. Co1 118 Jan 05, 2023
An open-source, mini imitation of GitHub Copilot for Emacs.

Second Mate An open-source, mini imitation of GitHub Copilot using EleutherAI GPT-Neo-2.7B (via Huggingface Model Hub) for Emacs. This is a much small

Sam Rawal 238 Dec 27, 2022
Tools for improving Python imports

imptools Tools for improving Python imports. Installation pip3 install imptools Overview Detailed docs import_path Import a module from any path on th

Danijar Hafner 7 Aug 07, 2022
🦆 Better duck-typing with mypy-compatible extensions to Protocol

🦆 Quacks If it walks like a duck and it quacks like a duck, then it must be a duck Thanks to PEP544, Python now has protocols: a way to define duck t

Arie Bovenberg 9 Nov 14, 2022
Tool for pinpointing circular imports in Python. Find cyclic imports in any project

Pycycle: Find and fix circular imports in python projects Pycycle is an experimental project that aims to help python developers fix their circular de

Vadim Kravcenko 311 Dec 15, 2022