Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update mypy #153

Merged
merged 1 commit into from
Apr 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ethpm/backends/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from abc import ABC, abstractmethod
from typing import Union

from ethpm.typing import URI

Expand Down Expand Up @@ -28,7 +29,7 @@ def can_translate_uri(self, uri: URI) -> bool:
pass

@abstractmethod
def fetch_uri_contents(self, uri: URI) -> bytes:
def fetch_uri_contents(self, uri: URI) -> Union[bytes, URI]:
"""
Fetch the contents stored at a URI.
"""
Expand Down
5 changes: 5 additions & 0 deletions ethpm/backends/ipfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,9 @@ def get_ipfs_backend(import_path: str = None) -> BaseIPFSBackend:
def get_ipfs_backend_class(import_path: str = None) -> Type[BaseIPFSBackend]:
if import_path is None:
import_path = os.environ.get("ETHPM_IPFS_BACKEND_CLASS", DEFAULT_IPFS_BACKEND)
if not import_path:
raise CannotHandleURI(
"Please provide an import class or set "
"`ETHPM_IPFS_BACKEND_CLASS` environment variable."
)
return import_string(import_path)
3 changes: 2 additions & 1 deletion ethpm/backends/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from ethpm.backends.base import BaseURIBackend
from ethpm.constants import INFURA_API_KEY
from ethpm.typing import URI
from ethpm.utils.registry import fetch_standard_registry_abi
from ethpm.utils.uri import parse_registry_uri
from ethpm.validation import is_valid_registry_uri
Expand All @@ -31,7 +32,7 @@ def can_translate_uri(self, uri: str) -> bool:
def can_resolve_uri(self, uri: str) -> bool:
return False

def fetch_uri_contents(self, uri: str) -> bytes:
def fetch_uri_contents(self, uri: str) -> URI:
"""
Return content-addressed URI stored at registry URI.
"""
Expand Down
18 changes: 7 additions & 11 deletions ethpm/contract.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict, List, Tuple, Type # noqa: F401
from typing import Any, Dict, List, Optional, Tuple, Type # noqa: F401

from eth_utils import combomethod, is_canonical_address, to_bytes, to_checksum_address
from eth_utils.toolz import assoc, curry, pipe
Expand All @@ -15,11 +15,11 @@ class LinkableContract(Contract):
contract factories with link references in their package's manifest.
"""

unlinked_references: Tuple[Dict[str, Any]] = None
linked_references: Tuple[Dict[str, Any]] = None
unlinked_references: Optional[Tuple[Dict[str, Any]]] = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the inner dict be mutable? If not maybe convert to FrozenDict at which point you could assign (frozendict(),) as a class property since it's immutable and then not have to worry about the setting of the default value in the constructor.

linked_references: Optional[Tuple[Dict[str, Any]]] = None
needs_bytecode_linking = None

def __init__(self, address: bytes = None, **kwargs: Any) -> None:
def __init__(self, address: bytes, **kwargs: Any) -> None:
if self.needs_bytecode_linking:
raise BytecodeLinkingError(
"Contract cannot be instantiated until its bytecode is linked."
Expand Down Expand Up @@ -90,13 +90,9 @@ def validate_attr_dict(self, attr_dict: Dict[str, str]) -> None:
"Unable to validate attr dict, this contract has no linked/unlinked references."
)

all_link_refs: Tuple[Any, ...]
if self.unlinked_references and self.linked_references:
all_link_refs = self.unlinked_references + self.linked_references
elif not self.unlinked_references:
all_link_refs = self.linked_references
else:
all_link_refs = self.unlinked_references
unlinked_refs = self.unlinked_references or ({},)
linked_refs = self.linked_references or ({},)
all_link_refs = unlinked_refs + linked_refs

all_link_names = [ref["name"] for ref in all_link_refs]
if set(attr_dict_names) != set(all_link_names):
Expand Down
2 changes: 1 addition & 1 deletion ethpm/deployments.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def __contains__(self, key: str) -> bool:

def get(self, key: str) -> Dict[str, str]:
self._validate_name_and_references(key)
return self.deployment_data.get(key)
return self.deployment_data[key]

def items(self) -> ItemsView[str, Dict[str, str]]:
item_dict = {name: self.get(name) for name in self.deployment_data}
Expand Down
8 changes: 5 additions & 3 deletions ethpm/package.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import json
from pathlib import Path
from typing import Any, Dict, Generator, Tuple, Union
from typing import Any, Dict, Generator, Optional, Tuple, Union

from eth_utils import to_canonical_address, to_text, to_tuple
from web3 import Web3
Expand Down Expand Up @@ -45,7 +45,9 @@


class Package(object):
def __init__(self, manifest: Dict[str, Any], w3: Web3, uri: str = None) -> None:
def __init__(
self, manifest: Dict[str, Any], w3: Web3, uri: Optional[str] = None
) -> None:
"""
A package should be created using one of the available
classmethods and a valid w3 instance.
Expand Down Expand Up @@ -130,7 +132,7 @@ def manifest_version(self) -> str:
return self.manifest["manifest_version"]

@property
def uri(self) -> str:
def uri(self) -> Optional[str]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why Optional? Assuming this is to take into account packages initialized without a URI, what if we just generated a data URI for those? Data URIs could always be valid since they contain their content.

"""
The uri (local file_path / content-addressed URI) of a ``Package``'s manifest.
"""
Expand Down
5 changes: 3 additions & 2 deletions ethpm/utils/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def resolve_uri_contents(uri: URI, fingerprint: bool = None) -> bytes:
if resolvable_backends:
for backend in resolvable_backends:
try:
contents = backend().fetch_uri_contents(uri)
# ignore type b/c resolvable backends only return uri contents
contents: bytes = backend().fetch_uri_contents(uri) # type: ignore
except CannotHandleURI:
continue
return contents
Expand All @@ -44,7 +45,7 @@ def resolve_uri_contents(uri: URI, fingerprint: bool = None) -> bytes:
"Registry URIs must point to a resolvable content-addressed URI."
)
package_id = RegistryURIBackend().fetch_uri_contents(uri)
return resolve_uri_contents(package_id, True) # type: ignore
return resolve_uri_contents(package_id, True)

raise CannotHandleURI(
f"URI: {uri} cannot be resolved by any of the available backends."
Expand Down
4 changes: 2 additions & 2 deletions ethpm/utils/deployments.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ def validate_linked_references(
for idx, offset in enumerate(offsets):
value = values[idx]
# https://github.com/python/mypy/issues/4975
offset_value = int(offset) # type: ignore
dep_length = len(value) # type: ignore
offset_value = int(offset)
dep_length = len(value)
end_of_bytes = offset_value + dep_length
# Ignore b/c whitespace around ':' conflict b/w black & flake8
actual_bytes = bytecode[offset_value:end_of_bytes] # noqa: E203
Expand Down
14 changes: 10 additions & 4 deletions ethpm/utils/ipfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from typing import Dict
from urllib import parse

from google.protobuf.descriptor import Descriptor

from ethpm.pb.ipfs_file_pb2 import Data, PBNode
from ethpm.utils.base58 import b58encode

Expand Down Expand Up @@ -69,11 +71,14 @@ def multihash(value: bytes) -> bytes:
return multihash_bytes


def serialize_bytes(file_bytes: bytes) -> PBNode:
def serialize_bytes(file_bytes: bytes) -> Descriptor:
file_size = len(file_bytes)

data_protobuf = Data(
Type=Data.DataType.Value("File"), Data=file_bytes, filesize=file_size
# type ignored b/c DataType is manually attached in ipfs_file_pb2.py
Type=Data.DataType.Value("File"), # type: ignore
Data=file_bytes,
filesize=file_size,
)
data_protobuf_bytes = data_protobuf.SerializeToString()

Expand All @@ -83,7 +88,8 @@ def serialize_bytes(file_bytes: bytes) -> PBNode:


def generate_file_hash(content_bytes: bytes) -> str:
file_protobuf = serialize_bytes(content_bytes)
file_protobuf_bytes = file_protobuf.SerializeToString()
file_protobuf: Descriptor = serialize_bytes(content_bytes)
# type ignored b/c SerializeToString is manually attached in ipfs_file_pb2.py
file_protobuf_bytes = file_protobuf.SerializeToString() # type: ignore
file_multihash = multihash(file_protobuf_bytes)
return b58encode(file_multihash)
2 changes: 1 addition & 1 deletion ethpm/utils/manifest_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def validate_manifest_exists(manifest_id: str) -> None:
)


def format_manifest(manifest: Manifest, *, prettify: bool) -> str:
def format_manifest(manifest: Manifest, *, prettify: bool = None) -> str:
if prettify:
return json.dumps(manifest, sort_keys=True, indent=4)
return json.dumps(manifest, sort_keys=True, separators=(",", ":"))
Expand Down
8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
'tox>=1.8.0,<2',
],
'lint': [
'black>=18.6b4,<19',
'isort>=4.2.15,<5',
'flake8>=3.5.0,<4',
'mypy<0.600',
'black>=19.3b0,<20',
'isort>=4.3.17,<5',
'flake8>=3.7.0,<4',
'mypy<0.800',
],
'doc': [
'Sphinx>=1.5.5,<2',
Expand Down
4 changes: 2 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ envlist=
[isort]
combine_as_imports=True
force_sort_within_sections=True
include_trailing_comma=True
skip=__init__.py
include_trailing_comma=True
known_third_party=pytest,requests_mock
known_first_party=ethpm
line_length=88
Expand Down Expand Up @@ -43,6 +43,6 @@ deps=flake8
extras=lint
commands=
flake8 {toxinidir}/tests {toxinidir}/ethpm
mypy --follow-imports=silent --ignore-missing-imports --check-untyped-defs --disallow-incomplete-defs --disallow-untyped-defs --disallow-any-generics -p ethpm
mypy --follow-imports=silent --ignore-missing-imports --check-untyped-defs --disallow-incomplete-defs --disallow-untyped-defs --disallow-any-generics --warn-unused-ignore -p ethpm
black --check --diff {toxinidir}/ethpm/ --check --diff {toxinidir}/tests/
isort --check-only --recursive --diff {toxinidir}/ethpm/ {toxinidir}/tests/