wolframclient.serializers.encoders package


wolframclient.serializers.encoders.builtin module

wolframclient.serializers.encoders.builtin.encode_association(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_booleans(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_bytes(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_complex(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_dict(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_float(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_function(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_inputexpr(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_int(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_iter(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_none(serializer, o)[source]

None in Python ‘is frequently used to represent the absence of a value’ https://docs.python.org/3/library/constants.html#None

Null in the Wolfram Language ‘is a symbol used to indicate the absence of an expression or a result’, whereas None ‘is a setting used for certain options.’. Ref: http://reference.wolfram.com/language/ref/Null.html and http://reference.wolfram.com/language/ref/None.html

Python None is similar to Null when it means absence of value, like in:

def foo():

foo() # None
foo[] := (nothing;)
foo[] // InputForm  (* Null *)

Both are usually suppressed similarly, None and Null are not displayed, whereas [None] and {Null} are.

On the other hand Python None is similar to Wolfram Language None when it comes to option values, like in:

def my_function(*args, option: None):
    if option is None:
        # ....

Obviously the mapping of None is not straight forward. The options are:

  1. map Null and None to Python None.
  2. map Null to Python None.
  3. map None to Python None.

1. One symbol no more round trips. In the Wolfram Language None has a specific meaning and is used and tested explicitly, so it has to be Null that no more round trips. Null is never really used as a specific value, but more as a specific output meaning no output. From Python, testing if a WL function has returned something is consistent with Python functions. From the Wolfram Language, Python functions not returning will return None and therefore their output inconsistent. When the result is part of a bigger expression, checking for one value (Null) or the other (None) is roughly equivalent, especially as long as the library returns the same symbol.

2. Python None is mapped to Null and None to WLSymbol('None'). It create a UX issue, in the sense that wl.None is not available because None is reserved keyword. Testing if functions have returned is consistent and straight forward in both languages. We lose the opportunity to preserve the name None, which can cause confusion. Null can easily be represented in Python even though that’s certainly less useful than a straight forward representation of None with None.

3. Functions that do not return in Python, now return None symbol. The result is not suppressed consistently in both languages. Similarly, on the Python side, a Wolfram Language function result must be compared to wl.Null to check if the function returned anything.

Having inconsistencies between functions that return nothing is not an small issue, and could lead to all sort of hack and work around solutions to prevent them. That’s why we prioritize option 2 over the others.

wolframclient.serializers.encoders.builtin.encode_serializable(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_symbol(serializer, o)[source]
wolframclient.serializers.encoders.builtin.encode_text(serializer, o)[source]

wolframclient.serializers.encoders.datetime module

wolframclient.serializers.encoders.datetime.encode_date(serializer, o)[source]
wolframclient.serializers.encoders.datetime.encode_datetime(serializer, o)[source]
wolframclient.serializers.encoders.datetime.encode_time(serializer, o)[source]
wolframclient.serializers.encoders.datetime.encode_timedelta(serializer, o)[source]
wolframclient.serializers.encoders.datetime.encode_tzinfo(serializer, o)[source]

wolframclient.serializers.encoders.decimal module

wolframclient.serializers.encoders.decimal.encode_decimal(serializer, o)[source]

wolframclient.serializers.encoders.fractions module

wolframclient.serializers.encoders.fractions.encode_faction(serializer, o)[source]

wolframclient.serializers.encoders.numpy module

wolframclient.serializers.encoders.numpy.PACKEDARRAY_NUMPY_MAPPING = {<class 'numpy.int8'>: ('Integer8', None), <class 'numpy.int16'>: ('Integer16', None), <class 'numpy.int32'>: ('Integer32', None), <class 'numpy.int64'>: ('Integer64', None), <class 'numpy.uint8'>: ('Integer16', <class 'numpy.int16'>), <class 'numpy.uint16'>: ('Integer32', <class 'numpy.int32'>), <class 'numpy.uint32'>: ('Integer64', <class 'numpy.int64'>), <class 'numpy.float32'>: ('Real32', None), <class 'numpy.float64'>: ('Real64', None), <class 'numpy.complex64'>: ('ComplexReal32', None), <class 'numpy.complex128'>: ('ComplexReal64', None)}

Maps numpy dtype to appropriate wxf packed array type, eventually specifying the type to cast the data to.

wolframclient.serializers.encoders.numpy.encode_complex(serializer, o)[source]
wolframclient.serializers.encoders.numpy.encode_ndarray(serializer, o)[source]
wolframclient.serializers.encoders.numpy.encode_numpy_floating(serializer, o)[source]
wolframclient.serializers.encoders.numpy.encode_numpy_int(serializer, o)[source]
wolframclient.serializers.encoders.numpy.encode_numpy_mp_float(serializer, o)[source]
wolframclient.serializers.encoders.numpy.encode_packed_array(serializer, o)[source]
wolframclient.serializers.encoders.numpy.to_little_endian(array, inplace=False)[source]

Return a numpy array of the same type with little endian byte ordering.

Set inplace to True to mutate the input array.

wolframclient.serializers.encoders.pandas module

wolframclient.serializers.encoders.pandas.encode_as_association(serializer, o, length)[source]
wolframclient.serializers.encoders.pandas.encode_as_dataset(serializer, o, length)[source]
wolframclient.serializers.encoders.pandas.encode_as_list(serializer, o, length)[source]
wolframclient.serializers.encoders.pandas.encode_as_timeseries(serializer, o, length)[source]
wolframclient.serializers.encoders.pandas.encode_dataframe_as_assoc(serializer, o, length)[source]
wolframclient.serializers.encoders.pandas.encode_dataframe_as_dataset(serializer, o, length)[source]
wolframclient.serializers.encoders.pandas.encode_multiindex_as_assoc(serializer, o, length)[source]
wolframclient.serializers.encoders.pandas.encode_multiindex_as_dataset(serializer, o, length)[source]
wolframclient.serializers.encoders.pandas.encode_panda_series(serializer, o)[source]
wolframclient.serializers.encoders.pandas.encoded_kv_tuples(serializer, o)[source]
wolframclient.serializers.encoders.pandas.encoder_panda_dataframe(serializer, o)[source]
wolframclient.serializers.encoders.pandas.get_series_encoder_from_index(index, use_ts, form)[source]

Check property pandas_series_head only if specified (not None).


Return the length of a pandas Series and DataFrame as expected for WL serialization.

  • The length of a Series is the only value of the tuple shape.
  • The length of a dataframe is the number of columns. It’s the second value of shape.

This function is safe, when the shape does not have the expected number of elements, it fails silently and returns None, the object is later traversed to find out how many elements it contains.

wolframclient.serializers.encoders.pil module

wolframclient.serializers.encoders.pil.encode_image(serializer, img)[source]
wolframclient.serializers.encoders.pil.encoder = <wolframclient.utils.dispatch.Dispatch object>

Serialize a given PIL.Image into a Wolfram Language image.

This method first tries to extract the data and relevant information about the image, and reconstruct it using Image constructor. This is the most efficient way to proceed, but is not guaranteed to work all the time. Only some pixel representations are supported, fortunatelly the most common ones.

When the internal PIL representation does not correspond to one of the Wolfram Language, the image is converted to its format, if specified, or ultimately to PNG. This may fail, in which case an exception is raised and there is nothing more we can do.

In theory we could represent any image, but due to convert() behavior we can’t. This function is not converting, but naively casts to a given type without rescaling. e.g. int32 values above 255 converted to bytes become 255. We can’t cast properly from ‘I’ mode since some format are using ‘I’ for say ‘I;16’ (int16) and the rawmode is not always accessible.

See bug in convert: https://github.com/python-pillow/Pillow/issues/3159


Module contents