Skip to content

Commit

Permalink
[dmlab_module_test, docs] Modify Python test to work in both Python 2…
Browse files Browse the repository at this point in the history
….7 and Python 3.

Also add an optional new dependency on the "six" package that is now
used by this test. The remainder of DMLab is still usable without this
package.

Update documentation to point out the experimental Py3 support.
  • Loading branch information
tkoeppe committed Apr 6, 2018
1 parent 8caccaf commit 3fd8582
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 20 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,9 @@ software libraries, which we ship in several different ways:
use can use either hardware-accelerated rendering via EGL or GLX or
software rendering via OSMesa, depending on the `--define headless=...`
build setting.
* Python 2.7 (other versions might work, too) with NumPy and PIL. (A few
tests require a NumPy version of at least 1.8.)
* Python 2.7 (other versions might work, too) with NumPy, PIL. (A few
tests require a NumPy version of at least 1.8.) One test requires six
to demonstrate Python 3 compatibility.

The build rules are using a few compiler settings that are specific to GCC. If
some flags are not recognized by your compiler (typically those would be
Expand Down
6 changes: 6 additions & 0 deletions docs/users/python_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ usage, there is
[python/random_agent.py](../../python/random_agent.py), and
[python/random_agent_simple.py](../../python/random_agent_simple.py).

**A note about Python 3:** By and large the Python API requires Python 2.7.
However, there is experimental support for Python 3. Under Python 3, strings
coming out of the environment (e.g. event names or string observations) have to
be valid UTF-8. The `dmlab_module_test.py` demonstrates how to write code that
works both in Python 2.7 and Python 3 (using the `six` package).

### class `deepmind_lab.Lab`(*level*, *observations*, *config={}*, *renderer='software'*)

Creates an environment object, loading the game script file *level*. The
Expand Down
35 changes: 17 additions & 18 deletions python/tests/dmlab_module_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import os
import unittest
import numpy as np
import six

import deepmind_lab

Expand All @@ -31,7 +32,7 @@ class DeepMindLabTest(unittest.TestCase):
def testInitArgs(self):
with self.assertRaisesRegexp(TypeError, 'must be dict, not list'):
deepmind_lab.Lab('tests/empty_room_test', [], ['wrongconfig'])
with self.assertRaisesRegexp(TypeError, 'str'):
with self.assertRaisesRegexp(TypeError, 'str|bad argument type'):
deepmind_lab.Lab('tests/empty_room_test', [], {'wrongtype': 3})
with self.assertRaisesRegexp(TypeError, 'must be list, not None'):
deepmind_lab.Lab('tests/empty_room_test', None, {})
Expand Down Expand Up @@ -83,7 +84,7 @@ def testRun(self, steps=10, observation='RGB_INTERLACED'):
env = deepmind_lab.Lab('lt_chasm', [observation])
env.reset()

for _ in xrange(steps):
for _ in six.moves.range(steps):
obs = env.observations()
action = np.zeros((7,), dtype=np.intc)
reward = env.step(action, num_steps=4)
Expand All @@ -107,26 +108,25 @@ def testRunfilesPath(self):
self.assertTrue(os.stat(deepmind_lab.runfiles_path()))

def testWidthHeight(self, width=80, height=80, steps=10, num_steps=1):
observations = ['RGBD']
env = deepmind_lab.Lab('lt_chasm', observations,
config={'height': str(height),
'width': str(width)})
observation = 'RGBD'
env = deepmind_lab.Lab(
'lt_chasm', [observation],
config={'height': str(height), 'width': str(width)})
env.reset()

for _ in xrange(steps):
for _ in six.moves.range(steps):
obs = env.observations()
action = np.zeros((7,), dtype=np.intc)
reward = env.step(action, num_steps=num_steps)

self.assertEqual(obs[observations[0]].shape, (4, width, height))
self.assertEqual(obs[observation].shape, (4, width, height))
self.assertEqual(reward, 0.0)

def testStringObervations(self):
observation = 'CUSTOM_TEXT'
env = deepmind_lab.Lab(
'tests/text_observation_test', [observation],
config={'height': str(32),
'width': str(32)})
config={'height': '32', 'width': '32'})
observation_spec = env.observation_spec()
observation_spec_lookup = {o['name']: o for o in observation_spec}
spec = observation_spec_lookup[observation]
Expand All @@ -138,8 +138,8 @@ def testStringObervations(self):

def testEvents(self):
env = deepmind_lab.Lab(
'tests/event_test', [], config={'height': str(32),
'width': str(32)})
'tests/event_test', [],
config={'height': '32', 'width': '32'})
env.reset(episode=1, seed=7)
events = env.events()
self.assertEqual(len(events), 4)
Expand Down Expand Up @@ -191,17 +191,16 @@ def testVeloctyObservations(self, width=80, height=80):
backward_action = - forward_action
look_sideways_action = np.array([512, 0, 0, 0, 0, 0, 0], dtype=np.intc)

env = deepmind_lab.Lab('seekavoid_arena_01', ['VEL.TRANS', 'VEL.ROT'],
config={'height': str(height),
'width': str(width),
'fps': '60'})
env = deepmind_lab.Lab(
'seekavoid_arena_01', ['VEL.TRANS', 'VEL.ROT'],
config={'height': str(height), 'width': str(width), 'fps': '60'})

env.reset(seed=1)

# Initial landing on the ground.
env.step(noop_action, num_steps=180)

for _ in xrange(3):
for _ in six.moves.range(3):
# Doing nothing should result in velocity observations of zero.
env.step(noop_action, num_steps=100)
obs = env.observations()
Expand All @@ -227,7 +226,7 @@ def testVeloctyObservations(self, width=80, height=80):

env.reset(seed=1)

for _ in xrange(3):
for _ in six.moves.range(3):
env.step(noop_action, num_steps=100)
obs = env.observations()
np.testing.assert_array_equal(obs['VEL.TRANS'], np.zeros((3,)))
Expand Down

0 comments on commit 3fd8582

Please sign in to comment.