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

Add mypy type checking #7

Merged
merged 1 commit into from
Dec 1, 2017
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
Add mypy typechecking
  • Loading branch information
mdboom committed Dec 1, 2017
commit 9c7e5739fb9278e9fa06361f1b61e88c548b3d75
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ install:
- pushd tmp ; pip install -r ../requirements_dev.txt ; popd
- pushd tmp ; pip install -r ../requirements.txt ; popd
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then pip install enum34; fi
- if [[ $TRAVIS_PYTHON_VERSION == 3.6 ]]; then pip install mypy; fi
- pushd tmp ; pip install codecov ; popd
- python setup.py build_ext --inplace

script:
- if [[ $TRAVIS_PYTHON_VERSION == 3.6 ]]; then make lint; fi
- py.test --cov
- make lint

after_success:
- bash <(curl -s https://codecov.io/bash)
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ clean-test: ## remove test and coverage artifacts

lint: ## check style with flake8
flake8 pytoshop tests
mypy --py2 -p pytoshop

test: ## run tests quickly with the default Python
py.test
Expand Down
3 changes: 2 additions & 1 deletion conda-environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ dependencies:
- numpy >=1.11
- pytest
- pytest-cov
- python >=3.5
- python
- sphinx >=1.4.0
- coverage
- flake8
- six
- typing
3 changes: 2 additions & 1 deletion conda-environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ name: pytoshop
dependencies:
- cython >=0.24
- numpy >=1.11
- python >=3.5
- python
- six
- typing
5 changes: 5 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[mypy]
show_none_errors = True
strict_optional = True
ignore_missing_imports = True
follow_imports = skip
4 changes: 4 additions & 0 deletions pytoshop/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
__version__ = '1.1.0'


from typing import BinaryIO # NOQA


def read(fd):
# type: (BinaryIO) -> PsdFile
"""
Read a PSD file from a file-like object.

Expand Down
76 changes: 51 additions & 25 deletions pytoshop/blending_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,24 @@
from . import util


from typing import BinaryIO, List, Optional, TYPE_CHECKING # NOQA
if TYPE_CHECKING:
from . import core # NOQA


class BlendingRange(object):
"""
Blending range data.

Comprises 2 black values and 2 white values.
"""
def __init__(self, black0=0, black1=0, white0=0, white1=0, _values=None):
def __init__(self,
black0=0, # type: int
black1=0, # type: int
white0=0, # type: int
white1=0, # type: int
_values=None # type: Optional[np.ndarray]
): # type: (...) -> None
if _values is not None:
self._values = _values
else:
Expand All @@ -31,40 +42,41 @@ def __init__(self, black0=0, black1=0, white0=0, white1=0, _values=None):
np.uint8)

@property
def black0(self):
def black0(self): # type: (...) -> int
return self._values[0]

@black0.setter
def black0(self, val):
def black0(self, val): # type: (int) -> None
self._values[0] = val

@property
def black1(self):
def black1(self): # type: (...) -> int
return self._values[1]

@black1.setter
def black1(self, val):
def black1(self, val): # type: (int) -> None
self._values[1] = val

@property
def white0(self):
def white0(self): # type: (...) -> int
return self._values[2]

@white0.setter
def white0(self, val):
def white0(self, val): # type: (int) -> None
self._values[2] = val

@property
def white1(self):
def white1(self): # type: (...) -> int
return self._values[3]

@white1.setter
def white1(self, val):
def white1(self, val): # type: (int) -> None
self._values[3] = val

@classmethod
@util.trace_read
def read(cls, fd):
# type: (BinaryIO) -> BlendingRange
buf = fd.read(4)
values = np.frombuffer(buf, np.uint8)

Expand All @@ -77,6 +89,7 @@ def read(cls, fd):

@util.trace_write
def write(self, fd, header):
# type: (BinaryIO, core.Header) -> None
fd.write(self._values.tobytes())
write.__doc__ = docs.write

Expand All @@ -87,7 +100,10 @@ class BlendingRangePair(object):

The combination of a source and destination blending range.
"""
def __init__(self, src=None, dst=None):
def __init__(self,
src=None, # type: Optional[BlendingRange]
dst=None # type: Optional[BlendingRange]
): # type: (...) -> None
if src is None:
src = BlendingRange()
if dst is None:
Expand All @@ -96,36 +112,37 @@ def __init__(self, src=None, dst=None):
self._dst = dst

@property
def src(self):
def src(self): # type: (...) -> BlendingRange
return self._src

@src.setter
def src(self, val):
def src(self, val): # type: (BlendingRange) -> None
if not isinstance(val, BlendingRange):
raise TypeError("src must be BlendingRange instance")
self._src = val

@property
def dst(self):
def dst(self): # type: (...) -> BlendingRange
return self._dst

@dst.setter
def dst(self, val):
def dst(self, val): # type: (BlendingRange) -> None
if not isinstance(val, BlendingRange):
raise TypeError("dst must be BlendingRange instance")
self._dst = val

def length(self, header):
def length(self, header): # type: (core.Header) -> int
return 8
length.__doc__ = docs.length
length.__doc__ = docs.length # type: ignore

def total_length(self, header):
def total_length(self, header): # type: (core.Header) -> int
return self.length(header)
total_length.__doc__ = docs.total_length
total_length.__doc__ = docs.total_length # type: ignore

@classmethod
@util.trace_read
def read(cls, fd):
# type: (BinaryIO) -> BlendingRangePair
src = BlendingRange.read(fd)
dst = BlendingRange.read(fd)

Expand All @@ -134,6 +151,7 @@ def read(cls, fd):

@util.trace_write
def write(self, fd, header):
# type: (BinaryIO, core.Header) -> None
self.src.write(fd, header)
self.dst.write(fd, header)
write.__doc__ = docs.write
Expand All @@ -146,19 +164,24 @@ class BlendingRanges(object):
Consists of a composite gray blend pair followed by N additional
pairs.
"""
def __init__(self, composite_gray_blend=None, channels=None):
def __init__(
self,
composite_gray_blend=None, # type: Optional[BlendingRangePair]
channels=None # type: Optional[List[BlendingRangePair]]
): # type: (...) -> None
self.composite_gray_blend = composite_gray_blend
if channels is None:
channels = []
self.channels = channels

@property
def composite_gray_blend(self):
def composite_gray_blend(self): # type: (...) -> BlendingRangePair
"""Composite gray `BlendingRangePair`."""
return self._composite_gray_blend

@composite_gray_blend.setter
def composite_gray_blend(self, value):
# type: (BlendingRangePair) -> None
if (value is not None and
not isinstance(value, BlendingRangePair)):
raise TypeError(
Expand All @@ -168,16 +191,17 @@ def composite_gray_blend(self, value):
self._composite_gray_blend = value

@property
def channels(self):
def channels(self): # type: (...) -> List[BlendingRangePair]
"""List of additional `BlendingRangePair` instances."""
return self._channels

@channels.setter
def channels(self, value):
# type: (List[BlendingRangePair]) -> None
util.assert_is_list_of(value, BlendingRangePair)
self._channels = value

def length(self, header):
def length(self, header): # type: (core.Header) -> int
if (self.composite_gray_blend is not None or
len(self.channels)):
if self.composite_gray_blend is None:
Expand All @@ -188,15 +212,16 @@ def length(self, header):
composite_gray_blend.total_length(header) +
sum(x.total_length(header) for x in self.channels))
return 0
length.__doc__ = docs.length
length.__doc__ = docs.length # type: ignore

def total_length(self, header):
def total_length(self, header): # type: (core.Header) -> int
return 4 + self.length(header)
total_length.__doc__ = docs.total_length
total_length.__doc__ = docs.total_length # type: ignore

@classmethod
@util.trace_read
def read(cls, fd, num_channels):
# type: (BinaryIO, int) -> BlendingRanges
length = util.read_value(fd, 'I')
end = fd.tell() + length
util.log("length: {}, end: {}", length, end)
Expand All @@ -217,6 +242,7 @@ def read(cls, fd, num_channels):

@util.trace_write
def write(self, fd, header):
# type: (BinaryIO, core.Header) -> None
util.write_value(fd, 'I', self.length(header))
if (self.composite_gray_blend is not None or
len(self.channels)):
Expand Down
Loading