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 "_CLE@BooleanClauseList" 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
Mypy stubs, i.e., type information, for numpy, pandas and matplotlib

Mypy type stubs for NumPy, pandas, and Matplotlib This is a PEP-561-compliant stub-only package which provides type information for matplotlib, numpy

Predictive Analytics Lab 194 Dec 19, 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 3, 2023
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 plugin for Flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle.

flake8-bugbear A plugin for Flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycode

Python Code Quality Authority 869 Dec 30, 2022
The strictest and most opinionated python linter ever!

wemake-python-styleguide Welcome to the strictest and most opinionated python linter ever. wemake-python-styleguide is actually a flake8 plugin with s

wemake.services 2.1k Jan 1, 2023
coala provides a unified command-line interface for linting and fixing all your code, regardless of the programming languages you use.

"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." ― John F. Woods coala provides a

coala development group 3.4k Dec 29, 2022
Automated security testing using bandit and flake8.

flake8-bandit Automated security testing built right into your workflow! You already use flake8 to lint all your code for errors, ensure docstrings ar

Tyler Wince 96 Jan 1, 2023
Easy saving and switching between multiple KDE configurations.

Konfsave Konfsave is a config manager. That is, it allows you to save, back up, and easily switch between different (per-user) system configurations.

null 42 Sep 25, 2022
A framework for detecting, highlighting and correcting grammatical errors on natural language text.

Gramformer Human and machine generated text often suffer from grammatical and/or typographical errors. It can be spelling, punctuation, grammatical or

Prithivida 1.3k Jan 8, 2023
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 3, 2022
PEP-484 stubs for Django

pep484 stubs for Django This package contains type stubs and a custom mypy plugin to provide more precise static types and type inference for Django f

TypedDjango 1.1k Dec 30, 2022
PEP-484 stubs for django-rest-framework

pep484 stubs for Django REST framework Mypy stubs for DRF 3.12.x. Supports Python 3.6, 3.7, 3.8 and 3.9. Installation pip install djangorestframework-

TypedDjango 303 Dec 27, 2022
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 5, 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 8, 2023
Typing-toolbox for Python 3 _and_ 2.7 w.r.t. PEP 484.

Welcome to the pytypes project pytypes is a typing toolbox w.r.t. PEP 484 (PEP 526 on the road map, later also 544 if it gets accepted). Its main feat

Stefan Richthofer 188 Dec 29, 2022
Auto-generate PEP-484 annotations

PyAnnotate: Auto-generate PEP-484 annotations Insert annotations into your source code based on call arguments and return types observed at runtime. F

Dropbox 1.4k Dec 26, 2022
Auto-generate PEP-484 annotations

PyAnnotate: Auto-generate PEP-484 annotations Insert annotations into your source code based on call arguments and return types observed at runtime. F

Dropbox 1.4k Dec 26, 2022
Pydocstringformatter - A tool to automatically format Python docstrings that tries to follow recommendations from PEP 8 and PEP 257.

Pydocstringformatter A tool to automatically format Python docstrings that tries to follow recommendations from PEP 8 and PEP 257. See What it does fo

Daniël van Noord 31 Dec 29, 2022
A PyPI mirror client according to PEP 381 http://www.python.org/dev/peps/pep-0381/

This is a PyPI mirror client according to PEP 381 + PEP 503 http://www.python.org/dev/peps/pep-0381/. bandersnatch >=4.0 supports Linux, MacOSX + Wind

Python Packaging Authority 345 Dec 28, 2022
A PyPI mirror client according to PEP 381 http://www.python.org/dev/peps/pep-0381/

This is a PyPI mirror client according to PEP 381 + PEP 503 http://www.python.org/dev/peps/pep-0381/. bandersnatch >=4.0 supports Linux, MacOSX + Wind

Python Packaging Authority 345 Dec 28, 2022