Skip to content

Commit

Permalink
Add mypy typechecking
Browse files Browse the repository at this point in the history
  • Loading branch information
mdboom committed Dec 1, 2017
1 parent 722555c commit e380da7
Show file tree
Hide file tree
Showing 19 changed files with 1,365 additions and 761 deletions.
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

0 comments on commit e380da7

Please sign in to comment.