Skip to content

Commit

Permalink
Merge pull request #3 from hx2A/release090a0
Browse files Browse the repository at this point in the history
release 0.9.0a0
  • Loading branch information
hx2A authored May 4, 2023
2 parents 42eb58c + 239ae6e commit 479699e
Show file tree
Hide file tree
Showing 84 changed files with 15,509 additions and 15,268 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

[![mybinder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/py5coding/py5examples/HEAD?urlpath=lab)

py5 is a new version of [**Processing**][processing] for Python 3.8+. It makes the Java [**Processing**][processing] jars available to the CPython interpreter using [**JPype**][jpype]. It can do just about all of the 2D and 3D drawing [**Processing**][processing] can do, except with Python instead of Java code.
py5 is a version of [**Processing**][processing] for Python 3.8+. It makes the Java [**Processing**][processing] jars available to the CPython interpreter using [**JPype**][jpype]. It can do just about all of the 2D and 3D drawing [**Processing**][processing] can do, except with Python instead of Java code.

The goal of py5 is to create a new version of Processing that is integrated into the Python ecosystem. Built into the library are thoughtful choices about how to best get py5 to work with other popular Python libraries and tools such as [Jupyter][jupyter], [numpy][numpy], and [Pillow][pillow].
The goal of py5 is to offer a new version of Processing that is integrated into the Python ecosystem. Built into the library are thoughtful choices about how to best get py5 to work with other popular Python libraries and tools such as [Jupyter][jupyter], [numpy][numpy], and [Pillow][pillow].

## Simple Example

Expand Down Expand Up @@ -46,14 +46,15 @@ pip install py5

## Getting Started

There are currently four basic ways to use py5. They are:
There are currently five basic ways to use py5. They are:

* **module mode**: create a sketch with `setup()` and `draw()` functions that call methods provided by the `py5` library. The above example is created in module mode.
* **class mode**: create a Python class inherited from `py5.Sketch`. This mode supports multiple Sketches running at the same time.
* **imported mode**: simplified code that omits the `py5.` prefix. This mode is supported by the py5 Jupyter notebook kernel and the `run_sketch` command line utility.
* **static mode**: functionless code to create static images. This mode is supported by the py5bot Jupyter notebook kernel, the `%%py5bot` IPython magic, and the `run_sketch` command line utility.
* **processing mode**: make calls to Python from a Processing (Java) Sketch. This mode enables py5 to function as bridge, connecting the Python and Java ecosystems through a new `callPython()` method.

The documentation website, [https://py5coding.org/](https://py5coding.org/), is a work in progress. The reference documentation is solid but the how-to's and tutorials are incomplete.
The documentation website, [https://py5coding.org/](https://py5coding.org/), is a work in progress, but contains solid reference documentation and many tutorials for beginner coders.

[py5generator][py5_generator_repo] is a meta-programming project that creates the py5 library. To view the actual installed py5 library code, look at the [py5 repository][py5_repo]. All py5 library development is done through py5generator.

Expand Down
10,163 changes: 5,130 additions & 5,033 deletions py5/__init__.py

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion py5/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# *****************************************************************************
#
# Part of the py5 library
# Copyright (C) 2020-2022 Jim Schmitz
# Copyright (C) 2020-2023 Jim Schmitz
#
# This library is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
Expand Down
24 changes: 11 additions & 13 deletions py5/bridge.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# *****************************************************************************
#
# Part of the py5 library
# Copyright (C) 2020-2022 Jim Schmitz
# Copyright (C) 2020-2023 Jim Schmitz
#
# This library is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
Expand Down Expand Up @@ -33,11 +33,7 @@
import py5_tools
from . import reference
from . import custom_exceptions
# from . import java_conversion

# *** stacktrace configuration ***
# set stackprinter color style. Default is plaintext. Other choices are darkbg,
# darkbg2, darkbg3, lightbg, lightbg2, lightbg3.
_stackprinter_style = 'plaintext'
# prune tracebacks to only show only show stack levels in the user's py5 code.
_prune_tracebacks = True
Expand Down Expand Up @@ -95,12 +91,13 @@ def handle_exception(println, exc_type, exc_value, exc_tb):
tb = exc_tb.tb_next
while hasattr(tb, 'tb_next') and hasattr(tb, 'tb_frame'):
f_code = tb.tb_frame.f_code
if f_code.co_filename.startswith(_MODULE_INSTALL_DIR):
if f_code.co_filename.startswith(
_MODULE_INSTALL_DIR) and not f_code.co_name.endswith('py5_no_prune'):
py5info.append((Path(f_code.co_filename[(len(_MODULE_INSTALL_DIR) + 1):]).parts,
f_code.co_name))
if trim_tb is None:
trim_tb = prev_tb
elif f_code.co_filename.startswith(_PY5TOOLS_MODULE_INSTALL_DIR):
elif f_code.co_filename.startswith(_PY5TOOLS_MODULE_INSTALL_DIR) and not f_code.co_name.endswith('py5_no_prune'):
py5info.append((Path(f_code.co_filename[(
len(_PY5TOOLS_MODULE_INSTALL_DIR) + 1):]).parts, f_code.co_name))
if trim_tb is None:
Expand Down Expand Up @@ -134,7 +131,7 @@ def handle_exception(println, exc_type, exc_value, exc_tb):
while m := _PY5_STATIC_CODE_FILENAME_REGEX.search(errmsg):
errmsg = errmsg[m.span()[1]:]
else:
errmsg = "py5 encountered an error in your code:" + errmsg
errmsg = "py5 encountered an error in your code:\n\n" + errmsg

println(errmsg, stderr=True)

Expand Down Expand Up @@ -174,8 +171,9 @@ def __init__(self, sketch):
self._current_running_method = None
self._is_terminated = False

from .java_conversion import convert_to_python_types
from .object_conversion import convert_to_python_types, convert_to_java_type
self._convert_to_python_types = convert_to_python_types
self._convert_to_java_type = convert_to_java_type

def set_functions(self, functions, function_param_counts):
self._function_param_counts = dict()
Expand Down Expand Up @@ -294,11 +292,11 @@ def call_function(self, key, params):
subd = d[s]
if isinstance(subd, dict):
d = subd
elif hasattr(subd, '__dict__'):
d = subd.__dict__
elif hasattr(subd, '__dir__') or hasattr(subd, '__dict__'):
d = {k: getattr(subd, k) for k in dir(subd)}
else:
return _JAVA_RUNTIMEEXCEPTION(
f'{s} in key {key} does map to dict or object with __dict__ attribute')
f'{s} in key {key} does not map to a dict or an object that can be inspected with dir()')
else:
return _JAVA_RUNTIMEEXCEPTION(
f'{s} not found with key {key}')
Expand All @@ -314,7 +312,7 @@ def call_function(self, key, params):
key)
if key in py5_tools.config._PY5_PROCESSING_MODE_KEYS:
py5_tools.config._PY5_PROCESSING_MODE_KEYS.pop(key)
return retval
return self._convert_to_java_type(retval)
except Exception as e:
handle_exception(self._sketch.println, *sys.exc_info())
return _JAVA_RUNTIMEEXCEPTION(str(e))
Expand Down
19 changes: 13 additions & 6 deletions py5/create_font_tool.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# *****************************************************************************
#
# Part of the py5 library
# Copyright (C) 2020-2022 Jim Schmitz
# Copyright (C) 2020-2023 Jim Schmitz
#
# This library is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
Expand Down Expand Up @@ -36,6 +36,13 @@ def __init__(
self.filename = filename or f'{font_name}-{font_size}.vlw'
self.characters = characters

def __str__(self) -> str:
return f"CreateFontTool(font_name='" + self.font_name + \
"', font_size=" + str(self.font_size) + ")"

def __repr__(self) -> str:
return self.__str__()

def settings(self):
self.size(400, 100, self.P2D)

Expand Down Expand Up @@ -103,16 +110,16 @@ def create_font_file(
By default it will create data files for every character available in the
specified font. To reduce execution time and output file size, limit the
characters using the ``characters`` parameter. The default output filename is
``{font_name}-{font_size}.vlw`` and will be saved to the current directory.
characters using the `characters` parameter. The default output filename is
`{font_name}-{font_size}.vlw` and will be saved to the current directory.
This utility function opens a window that displays a short message about the
number of glyphs written to the file. To make the window close automatically,
set the ``pause`` parameter to ``False``.
set the `pause` parameter to `False`.
Get a list of font names available on your computer with Py5Font's
``Py5Font.list()`` method. If you request an unavailable font, it will create
the data file anyway but using a default font."""
`Py5Font.list()` method. If you request an unavailable font, it will create the
data file anyway but using a default font."""
vlw_creator = CreateFontTool(font_name, font_size,
filename=filename, characters=characters,
pause=pause)
Expand Down
21 changes: 20 additions & 1 deletion py5/custom_exceptions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# *****************************************************************************
#
# Part of the py5 library
# Copyright (C) 2020-2022 Jim Schmitz
# Copyright (C) 2020-2023 Jim Schmitz
#
# This library is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
Expand All @@ -19,10 +19,14 @@
# *****************************************************************************
import re

import py5_tools

from . import reference
from . import spelling

JPYPE_TYPEERROR_REGEX = re.compile(
r'No matching overloads found for [\w\.]*(\([^\)]*\))')
IMPORTED_MODE_NAMEERROR_REGEX = re.compile(r"name '(\w+)' is not defined")


def handle_typeerror(exc_type_name, exc_msg, py5info):
Expand All @@ -46,6 +50,21 @@ def handle_typeerror(exc_type_name, exc_msg, py5info):
return exc_msg


def handle_nameerror(exc_type_name, exc_msg, py5info):
if py5_tools.imported.get_imported_mode():
m = IMPORTED_MODE_NAMEERROR_REGEX.match(exc_msg)
if m:
fname = m.group(1)
exc_msg = 'The name "' + fname + '" is not defined.'
suggestion_list = spelling.suggestions(
fname, py5_tools.reference.PY5_DIR_STR)
if suggestion_list:
exc_msg += ' Did you mean ' + suggestion_list + '?'

return exc_msg


CUSTOM_EXCEPTION_MSGS = dict(
TypeError=handle_typeerror,
NameError=handle_nameerror,
)
2 changes: 1 addition & 1 deletion py5/decorators.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# *****************************************************************************
#
# Part of the py5 library
# Copyright (C) 2020-2022 Jim Schmitz
# Copyright (C) 2020-2023 Jim Schmitz
#
# This library is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
Expand Down
Loading

0 comments on commit 479699e

Please sign in to comment.