mypy-zope


Namemypy-zope JSON
Version 1.0.4 PyPI version JSON
download
home_pagehttps://github.com/Shoobx/mypy-zope
SummaryPlugin for mypy to support zope interfaces
upload_time2024-03-12 19:54:19
maintainer
docs_urlNone
authorAndrey Lebedev
requires_python
license
keywords mypy zope interfaces typing
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Plugin for mypy to support zope.interface

[![Build Status](https://travis-ci.org/Shoobx/mypy-zope.svg?branch=master)](https://travis-ci.org/Shoobx/mypy-zope)
[![Coverage Status](https://coveralls.io/repos/github/Shoobx/mypy-zope/badge.svg)](https://coveralls.io/github/Shoobx/mypy-zope)
[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)

The goal is to be able to make zope interfaces to be treated as types in mypy
sense.

## Usage

Install both mypy and mypy-zope:
```sh
pip install mypy-zope
```

Edit `mypy.ini` file in your project to enable the plugin:

```ini
[mypy]
namespace_packages=True
plugins=mypy_zope:plugin
```

You're done! You can now check your project with mypy:

```sh
mypy your-project-dir
```

## What is supported?

You can browse
[sample files](https://github.com/Shoobx/mypy-zope/tree/master/tests/samples)
to get some sense on what features are supported and how they are handled.

### Interface declarations

You can define the interface and provide implementation:

```python
class IAnimal(zope.interface.Interface):
    def say() -> None:
        pass

@zope.interface.implementer(IAnimal)
class Cow(object):
    def say(self) -> None:
        print("Moooo")

animal: IAnimal = Cow()
animal.say()
```

The interface `IAnimal` will be treated as superclass of the implementation
`Cow`: you will be able to pass an implementation to functions accepting an
interface and all the usual polymorphism tricks.

It is also possible to declare the implementation using `classImplements`
function  with the same effect as `@imlementer` decorator. This is useful if
you do not control the code that defines the implementation class.

```python
classImplements(Cow, IAnimal)

animal: IAnimal = Cow()
```

### Schema field type inference
A limited support for defining attributes as `zope.schema.Field`s is supported too:

```python
class IAnimal(zope.interface.Interface):
    number_of_legs = zope.schema.Int(title="Number of legs")

@zope.interface.implementer(IAnimal)
class Cow(object):
    number_of_legs = 4
```

In context of an interface, some known `zope.schema` field types are
automatically translated to python types, so the `number_of_legs` attributes is
getting the type `int` in the example above. That means mypy will report an
error if you try to assign string to that attribute on an instance of `IAnimal`
type. Custom fields or fields not recognized by plugin are given type `Any`.

### Field properties

Support for `zope.schema.FieldProperty` is limited, because type information is
not transferred from an interface to implementation attribute, but mypy doesn't
report errors on sources like this:

```python
class IAnimal(zope.interface.Interface):
    number_of_legs = zope.schema.Int(title="Number of legs")

@zope.interface.implementer(IAnimal)
class Cow(object):
    number_of_legs = zope.schema.FieldProperty(IAnimal['number_of_legs'])
```

The type of `Cow.number_of_legs` will become `Any` in this case, even though
`IAnimal.number_of_legs` would be inferred as `int`.

### Adaptation pattern

Zope interfaces can be "called" to lookup an adapter, like this:

```python
class IEUPowerSocket(zope.interface.Interface):
    def fit():
        pass

adapter = IEUPowerSocket(us_plug)
adapter.fit()
```

Type of the `adapter` variable will be set to `IEUPowerSocket`.

### Conditional type inference

When using `zope.interface`'s `implementedBy()` and `providedBy()` methods
in an if statement, `mypy` will know which type it is inside those statements.

```python
if IAnimal.providedBy(ob):
    ob.number_of_legs += 2

```

### Declaration of overloaded methods in interfaces

Similarly to regular [overloaded
functions](https://docs.python.org/3/library/typing.html#typing.overload),
`@overload` declarations are supported in interfaces as well:

```python
class IAnimal(zope.interface.Interface):
    @overload
    def say() -> str:
        ...

    @overload
    def say(count: int) -> List[str]:
        ...

    def say(count: int = None) -> Union[str, List[str]]:
        pass


@zope.interface.implementer(IAnimal)
class Cow(object):
    @overload
    def say(self) -> str:
        ...

    @overload
    def say(self, count: int) -> List[str]:
        ...

    def say(self, count: int = None) -> Union[str, List[str]]:
        if count is None:
            return "Mooo"
        return ["Mooo"] * count
```

### Type stubs for zope.interface and zope.schema

`mypy-zope` ships with type stubs (`*.pyi` files) for `zope.interface` and
`zope.schema` packages. They are enabled automatically as soon as plugin is
enabled.


## What is not supported?

These `zope.interface` features are not supported:

* Declaring modules as interface implementers.
* Type inference for `zope.schema.List` and `zope.schema.Dict` fields.
* Stub files are largely incomplete
* Interface compatibility checker will not type-check non-method attributes

## Ready to use!

Currently, the project is used in production in various substantially large
projects and considered production-grade, however there still might be subtle
bugs around. Suggestions and pull requests are welcomed!


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/Shoobx/mypy-zope",
    "name": "mypy-zope",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "mypy,zope,interfaces,typing",
    "author": "Andrey Lebedev",
    "author_email": "andrey.lebedev@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/84/51/8d38eac4249560fe0267017a9671c85b5be663a14eff4033a72db6de33ac/mypy-zope-1.0.4.tar.gz",
    "platform": null,
    "description": "# Plugin for mypy to support zope.interface\n\n[![Build Status](https://travis-ci.org/Shoobx/mypy-zope.svg?branch=master)](https://travis-ci.org/Shoobx/mypy-zope)\n[![Coverage Status](https://coveralls.io/repos/github/Shoobx/mypy-zope/badge.svg)](https://coveralls.io/github/Shoobx/mypy-zope)\n[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)\n\nThe goal is to be able to make zope interfaces to be treated as types in mypy\nsense.\n\n## Usage\n\nInstall both mypy and mypy-zope:\n```sh\npip install mypy-zope\n```\n\nEdit `mypy.ini` file in your project to enable the plugin:\n\n```ini\n[mypy]\nnamespace_packages=True\nplugins=mypy_zope:plugin\n```\n\nYou're done! You can now check your project with mypy:\n\n```sh\nmypy your-project-dir\n```\n\n## What is supported?\n\nYou can browse\n[sample files](https://github.com/Shoobx/mypy-zope/tree/master/tests/samples)\nto get some sense on what features are supported and how they are handled.\n\n### Interface declarations\n\nYou can define the interface and provide implementation:\n\n```python\nclass IAnimal(zope.interface.Interface):\n    def say() -> None:\n        pass\n\n@zope.interface.implementer(IAnimal)\nclass Cow(object):\n    def say(self) -> None:\n        print(\"Moooo\")\n\nanimal: IAnimal = Cow()\nanimal.say()\n```\n\nThe interface `IAnimal` will be treated as superclass of the implementation\n`Cow`: you will be able to pass an implementation to functions accepting an\ninterface and all the usual polymorphism tricks.\n\nIt is also possible to declare the implementation using `classImplements`\nfunction  with the same effect as `@imlementer` decorator. This is useful if\nyou do not control the code that defines the implementation class.\n\n```python\nclassImplements(Cow, IAnimal)\n\nanimal: IAnimal = Cow()\n```\n\n### Schema field type inference\nA limited support for defining attributes as `zope.schema.Field`s is supported too:\n\n```python\nclass IAnimal(zope.interface.Interface):\n    number_of_legs = zope.schema.Int(title=\"Number of legs\")\n\n@zope.interface.implementer(IAnimal)\nclass Cow(object):\n    number_of_legs = 4\n```\n\nIn context of an interface, some known `zope.schema` field types are\nautomatically translated to python types, so the `number_of_legs` attributes is\ngetting the type `int` in the example above. That means mypy will report an\nerror if you try to assign string to that attribute on an instance of `IAnimal`\ntype. Custom fields or fields not recognized by plugin are given type `Any`.\n\n### Field properties\n\nSupport for `zope.schema.FieldProperty` is limited, because type information is\nnot transferred from an interface to implementation attribute, but mypy doesn't\nreport errors on sources like this:\n\n```python\nclass IAnimal(zope.interface.Interface):\n    number_of_legs = zope.schema.Int(title=\"Number of legs\")\n\n@zope.interface.implementer(IAnimal)\nclass Cow(object):\n    number_of_legs = zope.schema.FieldProperty(IAnimal['number_of_legs'])\n```\n\nThe type of `Cow.number_of_legs` will become `Any` in this case, even though\n`IAnimal.number_of_legs` would be inferred as `int`.\n\n### Adaptation pattern\n\nZope interfaces can be \"called\" to lookup an adapter, like this:\n\n```python\nclass IEUPowerSocket(zope.interface.Interface):\n    def fit():\n        pass\n\nadapter = IEUPowerSocket(us_plug)\nadapter.fit()\n```\n\nType of the `adapter` variable will be set to `IEUPowerSocket`.\n\n### Conditional type inference\n\nWhen using `zope.interface`'s `implementedBy()` and `providedBy()` methods\nin an if statement, `mypy` will know which type it is inside those statements.\n\n```python\nif IAnimal.providedBy(ob):\n    ob.number_of_legs += 2\n\n```\n\n### Declaration of overloaded methods in interfaces\n\nSimilarly to regular [overloaded\nfunctions](https://docs.python.org/3/library/typing.html#typing.overload),\n`@overload` declarations are supported in interfaces as well:\n\n```python\nclass IAnimal(zope.interface.Interface):\n    @overload\n    def say() -> str:\n        ...\n\n    @overload\n    def say(count: int) -> List[str]:\n        ...\n\n    def say(count: int = None) -> Union[str, List[str]]:\n        pass\n\n\n@zope.interface.implementer(IAnimal)\nclass Cow(object):\n    @overload\n    def say(self) -> str:\n        ...\n\n    @overload\n    def say(self, count: int) -> List[str]:\n        ...\n\n    def say(self, count: int = None) -> Union[str, List[str]]:\n        if count is None:\n            return \"Mooo\"\n        return [\"Mooo\"] * count\n```\n\n### Type stubs for zope.interface and zope.schema\n\n`mypy-zope` ships with type stubs (`*.pyi` files) for `zope.interface` and\n`zope.schema` packages. They are enabled automatically as soon as plugin is\nenabled.\n\n\n## What is not supported?\n\nThese `zope.interface` features are not supported:\n\n* Declaring modules as interface implementers.\n* Type inference for `zope.schema.List` and `zope.schema.Dict` fields.\n* Stub files are largely incomplete\n* Interface compatibility checker will not type-check non-method attributes\n\n## Ready to use!\n\nCurrently, the project is used in production in various substantially large\nprojects and considered production-grade, however there still might be subtle\nbugs around. Suggestions and pull requests are welcomed!\n\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "Plugin for mypy to support zope interfaces",
    "version": "1.0.4",
    "project_urls": {
        "Homepage": "https://github.com/Shoobx/mypy-zope"
    },
    "split_keywords": [
        "mypy",
        "zope",
        "interfaces",
        "typing"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9dc9627b58b9c48b1459f31869f216326b36bd75cb0c5efc2febe6857ccaa0de",
                "md5": "cca5a62edfefe964e7c27cdd57713f6f",
                "sha256": "c7298f93963a84f2b145c2b5cc98709fc2a5be4adf54bfe23fa7fdd8fd19c975"
            },
            "downloads": -1,
            "filename": "mypy_zope-1.0.4-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "cca5a62edfefe964e7c27cdd57713f6f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 32403,
            "upload_time": "2024-03-12T19:54:17",
            "upload_time_iso_8601": "2024-03-12T19:54:17.295747Z",
            "url": "https://files.pythonhosted.org/packages/9d/c9/627b58b9c48b1459f31869f216326b36bd75cb0c5efc2febe6857ccaa0de/mypy_zope-1.0.4-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "84518d38eac4249560fe0267017a9671c85b5be663a14eff4033a72db6de33ac",
                "md5": "c2e5f4d142b18b4ec59f6674a47a7fb9",
                "sha256": "a9569e73ae85a65247787d98590fa6d4290e76f26aabe035d1c3e94a0b9ab6ee"
            },
            "downloads": -1,
            "filename": "mypy-zope-1.0.4.tar.gz",
            "has_sig": false,
            "md5_digest": "c2e5f4d142b18b4ec59f6674a47a7fb9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 33879,
            "upload_time": "2024-03-12T19:54:19",
            "upload_time_iso_8601": "2024-03-12T19:54:19.546259Z",
            "url": "https://files.pythonhosted.org/packages/84/51/8d38eac4249560fe0267017a9671c85b5be663a14eff4033a72db6de33ac/mypy-zope-1.0.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-12 19:54:19",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Shoobx",
    "github_project": "mypy-zope",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "mypy-zope"
}
        
Elapsed time: 0.20434s