Skip to content

Commit

Permalink
Add method to get return type (#196)
Browse files Browse the repository at this point in the history
- Definitions now have a method `produces` which can be used to get the return type of a definition, it returns `typing.Any` is a return annotation is not given
- Alias pillow image `ar.Image`, which gives us the ability to change the representation in the future
- Parameterise build blog vscode task definition
  • Loading branch information
alcarney authored Mar 12, 2020
1 parent ced3bf4 commit 576815d
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 32 deletions.
44 changes: 25 additions & 19 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{
"label": "Build Blog",
"type": "shell",
"command": "${config:python.pythonPath} gallery.py --local",
"command": "${config:python.pythonPath} gallery.py ${input:blogArgs}",
"problemMatcher": [],
"group": "build",
"presentation": {
Expand All @@ -21,24 +21,6 @@
"cwd": "${workspaceRoot}/blog"
}
},
{
"label": "Build Blog (debug)",
"type": "shell",
"command": "${config:python.pythonPath} gallery.py -vv --local",
"problemMatcher": [],
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared",
"showReuseMessage": false,
"clear": true
},
"group": "build",
"options": {
"cwd": "${workspaceRoot}/blog"
}
},
{
"label": "Build Docs",
"type": "shell",
Expand Down Expand Up @@ -165,6 +147,30 @@
}
],
"default": "-e py38"
},
{
"id": "blogArgs",
"description": "Blog Arguments",
"type": "pickString",
"options": [
{
"label": "Local",
"value": "--local"
},
{
"label": "Local, skipping errors",
"value": "--local --skip-failures"
},
{
"label": "Local, debug",
"value": "-vv --local"
},
{
"label": "Local, debug, skipping errors",
"value": "-vv --local --skip-failures"
}
],
"default": "--local"
}
]
}
2 changes: 1 addition & 1 deletion arlunio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ._core import Collection, Definition, definition # noqa: F401
from ._expressions import all, any, clamp, invert, lerp # noqa: F401
from ._images import Resolutions, colorramp, encode, fill, save # noqa: F401
from ._images import Image, Resolutions, colorramp, encode, fill, save # noqa: F401
from ._version import __version__ # noqa: F401
10 changes: 10 additions & 0 deletions arlunio/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,16 @@ def attribs(self):
if not a.metadata[Definition.ATTR_ID]["inherited"]
}

@classmethod
def produces(cls):
"""Return the type of the object that this definition produces."""
rtype = inspect.signature(cls._definition).return_annotation

if rtype == inspect._empty:
return Any

return rtype


def _define_attribute(param: inspect.Parameter) -> attr.Attribute:
"""Given a parameter that represents some definition's attribute, write the
Expand Down
27 changes: 15 additions & 12 deletions arlunio/_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@
from typing import Optional

import numpy as np
import PIL.Image as Image
import PIL.ImageColor as Color
import PIL.Image as PImage
import PIL.ImageColor as PColor

from ._expressions import lerp

logger = logging.getLogger(__name__)

# Create a type alias that we're free to change in the future
Image = PImage.Image


class Resolutions(enum.Enum):
"""Enum that defines some common image resolutions
Expand Down Expand Up @@ -87,26 +90,26 @@ def encode(image) -> bytes:
return base64.b64encode(image_bytes)


def colorramp(values, start=None, stop=None):
def colorramp(values, start: Optional[str] = None, stop: Optional[str] = None) -> Image:
"""Given a range of values, produce an image mapping those values onto colors."""

(r, g, b) = Color.getrgb("#000") if start is None else Color.getrgb(start)
(R, G, B) = Color.getrgb("#fff") if stop is None else Color.getrgb(stop)
(r, g, b) = PColor.getrgb("#000") if start is None else PColor.getrgb(start)
(R, G, B) = PColor.getrgb("#fff") if stop is None else PColor.getrgb(stop)

reds = np.floor(lerp(r, R)(values))
greens = np.floor(lerp(g, G)(values))
blues = np.floor(lerp(b, B)(values))

pixels = np.array(np.dstack([reds, greens, blues]), dtype=np.uint8)
return Image.fromarray(pixels)
return PImage.fromarray(pixels)


def fill(
mask,
color: Optional[str] = None,
background: Optional[str] = None,
image: Optional[Image.Image] = None,
) -> Image.Image:
image: Optional[Image] = None,
) -> Image:
"""Given a mask, fill it in with a color.
Parameters
Expand All @@ -127,21 +130,21 @@ def fill(
Returns
-------
PIL.Image.Image
Image
An image with the region selected by the mask colored with the given color
"""

color = "#000" if color is None else color
fill_color = Color.getrgb(color)
fill_color = PColor.getrgb(color)

mask_img = Image.fromarray(mask)
mask_img = PImage.fromarray(mask)

if image is None:
background = "#fff" if background is None else background

height, width = mask.shape
image = Image.new("RGB", (width, height), color=background)
image = PImage.new("RGB", (width, height), color=background)

else:
image = image.copy()
Expand Down
26 changes: 26 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import inspect

from typing import Any

import arlunio as ar
import py.test

Expand Down Expand Up @@ -95,6 +97,30 @@ def Param(width, height, *, a: int = 0):
Param(a="string")


def test_definition_produces_any():
"""Ensure that a definition without a return annotation reports its return type as
:code:`Any`"""

@ar.definition()
def Param():
pass

assert Param.produces() == Any
assert Param().produces() == Any


def test_definition_produces():
"""Ensure that a definition reports what type it returns as declared by its return
annotation"""

@ar.definition()
def Param() -> int:
return 1

assert Param.produces() == int
assert Param().produces() == int


def test_derived_definition():
"""Ensure that we can derive a definition that's based on other definitions."""

Expand Down

0 comments on commit 576815d

Please sign in to comment.