Jep 3.8 Release Notes
*********************
This release is compatible with Python 2.7, 3.3, 3.4, 3.5, 3.6, and 3.7.
It is compatible with Java versions >= 1.7.


Maven layout
~~~~~~~~~~~~
The Jep source code and test code now follow a typical layout of Maven
projects.  The C code is organized following CPython's layout as a guideline.


Invoke using keyword args
~~~~~~~~~~~~~~~~~~~~~~~~~
Jep.invoke() now supports keyword arguments when invoking Python functions.
It continues to support varargs arguments and also supports a combination
of positional arguments and keyword arguments.


Python lists and tuples are converted to Java arrays
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It is now possible to pass a Python list or tuple to a Java method that is
expecting an array. A new array is created and each object in the Python
sequence is converted to a Java object and placed in the array.


Smarter library loading
~~~~~~~~~~~~~~~~~~~~~~~
Jep will try harder to find both the native Jep library and the Python library so
LD_PRELOAD, LD_LIBRARY_PATH and java.library.path are not needed in many
environments. There are 2 different changes that help with this:

1. Jep will now try to load the Python library globally which is required by some
   Python modules. Previously this global loading could be forced on Unix by using
   LD_PRELOAD.
2. If the native Jep Library is not found, then Jep will attempt to find it in
   the jep module. To find the jep module it looks in the locations in the
   PYTHONPATH environmental variable and also in the site-packages directory
   which is found relative to the PYTHONHOME environmental variable. If the Jep
   Library can be found in one of those locations then it is no longer necessary
   to set the LD_LIBRARY_PATH and/or java.library.path to the location of the
   Jep library.


PYTHONHOME can be set from Java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PyConfig can now be used to set the "home" directory for Python. This serves the
same purpose as the PYTHONHOME environmental variable. This value can be used by
Jep when trying to find the Jep native library and it is also used by Python to 
find the standard Python libraries.


Interface default methods can be called on JProxy objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When a Python object is wrapped in a Java interface (using jproxy) it will now
correctly call default methods on the Java interface that are not overridden by
the Python object.


Allow creation of Jep without a sub-interpreter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A new subclass of Jep has been created called SharedInterpreter. Instances of
this class can be used the same as an ordinary Jep instance but it will not use
a Python sub-interpreter. This is intended to improve compatibility with CPython
extension modules. For simple use cases this can provide an alternative to using
shared modules. Creating a SharedInterpreter is equivalent to sharing all
modules. See the JavaDoc on SharedInterpreter for more information on the
limitations and capabilities of this new mode.


Python Objects in Java (beta)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Wrapped Python objects can now be retrieved through the use of the new method
Jep.getValue(String, Class).  Provide the class of jep.python.PyObject or
jep.python.PyCallable to retrieve a Python object wrapped as a Java object.
These wrapped Python objects provide the methods getAttr(String),
getAttr(String, Class), setAttr(String, Object), and delAttr(String).  You can
creatively use and manipulate Python objects from Java by using
PyObject.getAttr(String, Class) repeatedly to access fields and methods and
PyCallable.call(...) to invoke retrieved methods.  The methods on a PyObject
can only be called from the Thread that created the PyObject.  Please see the
javadoc on the classes PyObject and PyCallable and their methods for more
information.  This feature is still considered to be in beta, it works well in
isolated testing but needs more real world testing in a variety of environments
to ensure it works consistently.  It is possible that the API may change in
future releases.


Compatibility Notes
*******************

Jep constructor now throws JepException if invalid thread state is detected
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Previously the Jep constructor(s) would print a warning to System.err when
a thread was reused for two active Jep instances.  Jep will now throw a
JepException when this state is detected to ensure stability.


Jep extends AutoCloseable and close() now throws JepException
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Jep now extends AutoCloseable instead of Closeable.  Along with this change,
Jep will throw a JepException if you try to close a Jep instance from a thread
other than the thread that constructed it.  This helps ensure stability.


Jep Constructors deprecated
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some of the Jep constructors have been deprecated in favor of using the
constructor Jep(JepConfig).  JepConfig also has a new method .createJep() for
an alternative method of creating Jep instances.


Jep pre-inits deprecated
~~~~~~~~~~~~~~~~~~~~~~~~
Using Jep.setInitParams(PyConfig) and Jep.setSharedModulesArgv(String...) have
been deprecated in favor of using the same methods on the new class
MainInterpreter.  As before, these methods must be called before instantiating
a Jep instance for them to take effect.  This is only an API change, the
functionality remains the same.


Jep printStack(bool) removed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Python method jep.printStack(bool) has been removed.  This could be used to
enable the printing of stacktraces to stdout when Java exceptions occur in
Python.  JepException has supported stacktraces since Jep 3.3 so the
printStack(bool) function was no longer as useful as it originally was and
hence it has been removed.


Jep Script Engine deprecated
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The classes JepScriptEngine and JepScriptEngineFactory have been deprecated since
they are not being used by the community.


Deprecations of PyModule and PyClass
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Java classes PyModule and PyClass have been deprecated in favor of the new
beta PyObject API.  In addition to this, the old set(String, Object) methods on
PyObject have been deprecated in favor of using setAttr(String, Object).  Also
Jep.createModule(String) has been deprecated as it will likely be replaced as
the new PyObject API evolves.

