Link

Python Commands

Table of contents

  1. Python Command
    1. Python statements
      1. Attribute accessing
      2. Method and function invoking
      3. Variable assignment
  2. Importing an External Module
  3. Command Factory

Python Command

The python command is the basic unit of work of PythonBridge. It allows developers to run arbitrary python code from Pharo. It is composed by a sequence of python statements, a collection of variable bindings, pharo observers callbacks and a transformation block.

Python statements

The python statements are created in Pharo by using Python3Generator.

Attribute accessing

Python objects instance variables and methods are accessible in Python by operator .. From Pharo, this operator is defined using => and allow accessing instance variables and invoking methods.

#foo asP3GI => #a    "foo.a"

Method and function invoking

Python functions and methods are called by using callWith: and callWith:with:.

The callWith: method receive as argument a collection of objects which corresponds to the positional arguments of the call.

#foo asP3GI callWith: #(1 2 3)    "foo(1,2,3)"

The callWith:with: method receives as first agument a collection of positional arguments and, as second argument, a dictionary of named arguments.

#foo asP3GI 
    callWith: #(1 2 3) 
    with: { 
        #nameArg1 -> 'bar'.
        #nameArg2 -> 5 } asDictionary

"foo(1, 2, 3, nameArg1='bar', nameArg2=5)"

Variable assignment

Assignments in python allow you to store objects in globals, temporary variables and instance variables. Python3Generator uses the message <- to assign the value at the right of the message to the receiver.

Assigning the temporary variable w with the array [1,2,3].

#foo asP3GI <- #(1 2 3)    "foo = [1,2,3]"

Assigning instance variable a from object in variable foo with the string 'bar'.

(#foo asP3GI => #a) <- 'bar'    "foo.a = 'bar'"

Importing an External Module

PythonBridge can interact with any python modules. Consider the numpy Python module, which essential in scientific computing. We will perform the following Python instruction within Smalltalk: numpy.arange(15).reshape(3, 5)

First, we need to augment the Pipenv environment with the numpy module. You can simply do it by modifying the Pipfile by adding the line numpy = "*". The complete Pipfile should be:

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
flask = "*"
requests = "*"
msgpack = "*"
numpy = "*"

[requires]
python_version = "3"

Once the Pipfile file modified, the pipenv environment must be upgraded, which can be done using the command line:

pipenv update

You should see something like:

➜  PythonBridge git:(master) ✗ pipenv update
Running $ pipenv lock then $ pipenv sync.
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
✔ Success! 
Updated Pipfile.lock (deca6d)!
Installing dependencies from Pipfile.lock (deca6d)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 14/14 — 00:00:07
To activate this project's virtualenv, run pipenv shell.
Alternatively, run a command inside the virtualenv with pipenv run.
All dependencies are now up-to-date!

Numpy is now installed in your Pipenv environment, and it is ready to be used from Smalltalk. You can do

PBApplication do: [ 
    "We import the numpy module"
	PBCF << (P3GImport moduleIdentifier: #numpy asP3GI).
    
    "We construct the Python expression numpy.arange(15).reshape(3, 5)"
	r := P3GCall target: (#numpy asP3GI => #arange) positionalArguments: #(15).
	PBCF << (P3GCall target: r => #reshape positionalArguments: #(3 5)). 
	s := PBCF send waitForValue.
    
    "The variable s points to a Smalltalk wrapper of the Python object"
    "We simply execute the Python expression str(s) to obtain a string that represents the numpy object"
	PBCF << (P3GCall target: #str asP3GI positionalArguments: (Array with: s)). 
	PBCF send waitForValue.
	 ].

Printing this expression will result in:

[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]

This small example shows how you can augment the Pipenv environment with a new Python module, and how you can access it from Smalltalk.

Command Factory

Each PythonBridge extension defines its own CommandFactory as a global object. In the case of PythonBridge it’s called PBCF and in KerasBridge is called KCF.