Metadata-Version: 2.1
Name: basedmypy
Version: 2.1.0
Summary: Based static typing for Python
Author: KotlinIsland
License: MIT License
Project-URL: News, https://github.com/KotlinIsland/basedmypy/releases
Project-URL: Documentation, https://KotlinIsland.github.io/basedmypy
Project-URL: Repository, https://github.com/KotlinIsland/basedmypy
Project-URL: Discord, https://discord.gg/7y9upqPrk2
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Software Development
Classifier: Typing :: Typed
Requires-Python: >=3.8
License-File: LICENSE
Requires-Dist: basedtyping (>=0.0.3)
Requires-Dist: typing-extensions (>=4.1.0)
Requires-Dist: mypy-extensions (>=1.0.0)
Requires-Dist: tomli (>=1.1.0) ; python_version < "3.11"
Provides-Extra: dmypy
Requires-Dist: psutil (>=4.0) ; extra == 'dmypy'
Provides-Extra: install-types
Requires-Dist: pip ; extra == 'install-types'
Provides-Extra: reports
Requires-Dist: lxml ; extra == 'reports'

.. image:: https://raw.githubusercontent.com/KotlinIsland/basedmypy/master/docs/static/logo-light.png

Basedmypy is a type checker that is built on top of the work done by the
`mypy project <https://github.com/python/mypy>`_. It adds based functionality and breaks compatibility with
the cringe parts of pep 484.

Based features
==============

Baseline
--------

Basedmypy has baseline, baseline is based! It allows you to adopt new strictness or features
without the burden of fixing up every usage, just save all current errors to the baseline
file and deal with them later.

Consider the following:

.. code-block:: python

    def foo(a):
        print(a)

.. code-block:: text

    > mypy demo.py
    demo.py:1: error: missing typehints
    Failed: errors found in source file


    > mypy --write-baseline demo.py
    demo.py:1: error: missing typehints
    Baseline successfully written to .mypy/baseline.json

    > mypy demo.py
    Success: no issues found in 1 source file

Then on subsequent runs the existing errors will be filtered out:

.. code-block:: python

    def foo(a):
        print(a)

    def bar(b: str, c: int) -> bool:
        return b + c

.. code-block:: text

    > mypy demo.py
    demo.py:4:5: error: Returning Any from function declared to return "bool"  [no-any-return]
    demo.py:4:16: error: Unsupported operand types for + ("str" and "int")  [operator]
    Found 2 errors in 1 file (checked 1 source file)

Intersection Types
------------------

Using the ``&`` operator or ``basedtyping.Intersection`` you can denote intersection types:

.. code-block:: python

    class Growable(ABC, Generic[T]):
        @abstractmethod
        def add(self, item: T): ...

    class Resettable(ABC):
        @abstractmethod
        def reset(self): ...

    def f(x: Resettable & Growable[str]):
        x.reset()
        x.add("first")

Type Joins
----------

Mypy joins types to their common base type:

.. code-block:: python

    a: int
    b: str
    reveal_type(a if bool() else b)  # Revealed type is "builtins.object"

Basedmypy joins types into unions instead:

.. code-block:: python

    a: int
    b: str
    reveal_type(a if bool() else b)  # Revealed type is "int | str"

Bare Literals
-------------

``Literal`` is so cumbersome! just use a bare literal instead:

.. code-block:: python

    class Color(Enum):
        RED = auto()

    a: 1 | 2
    b: True | Color.RED


Default Return Type
-------------------

The default return type of functions is ``None`` instead of ``Any``:
(configurable with the ``default_return`` option.)

.. code-block:: python

    def f(name: str):
        print(f"Hello, {name}!")

    reveal_type(f)  # (str) -> None

Generic ``TypeVar`` Bounds
--------------------------

Allows the bounds of ``TypeVar``\s to be generic.

So you are able to have functions with polymorphic generic parameters.

.. code-block:: python

    E = TypeVar("E")
    I = TypeVar("I", bound=Iterable[E])

    def foo(i: I, e: E) -> I:
        assert e not in i
        return i

    reveal_type(foo(["based"], "mypy"))  # N: Revealed type is "list[str]"
    reveal_type(foo({1, 2}, 3))  # N: Revealed type is "set[int]"

Overload Implementation Inference
---------------------------------

The types in overload implementations (including properties) can be inferred:

.. code-block:: python

    @overload
    def f(a: int) -> str: ...

    @overload
    def f(a: str) -> int: ...

    def f(a):
        reveal_type(a)  # int | str
        return None  # error: expected str | int

    class A:
        @property
        def foo(self) -> int: ...
        @foo.setter
        def foo(self, value): ...  # no need for annotations


Infer Function Parameters
-------------------------

Infer the type of a function parameter from it's default value:

.. code-block:: python

    def f(a=1, b=True):
        reveal_type((a, b))  # (int, bool)

Tuple Literal Types
-------------------

Basedmypy allows denotation of tuple types with tuple literals:

.. code-block:: python

    a: (int, str) = (1, "a")

Types in Messages
-----------------

Basedmypy makes significant changes to error and info messages, consider:

.. code-block:: python

    T = TypeVar("T", bound=int)

    def f(a: T, b: list[str | 1 | 2]) -> Never:
        reveal_type((a, b))

    reveal_type(f)

Mypy shows::

    Revealed type is "Tuple[T`-1, Union[builtins.str, Literal[1], Literal[2]]]"
    Revealed type is "def [T <: builtins.int] (a: T`-1, b: Union[builtins.str, Literal[1], Literal[2]]) -> <nothing>"

Basedmypy shows::

    Revealed type is "(T@f, str | 1 | 2)"
    Revealed type is "def [T: int] (a: T, b: str | 1 | 2) -> Never"
