Support kwargs in gym.make and export register
diff --git a/gym/__init__.py b/gym/__init__.py
index ec6623a3f3d..4ee968c1052 100644
--- a/gym/__init__.py
+++ b/gym/__init__.py
@@ -8,7 +8,7 @@
 from gym.version import VERSION as __version__
 
 from gym.core import Env, GoalEnv, Space, Wrapper, ObservationWrapper, ActionWrapper, RewardWrapper
-from gym.envs import make, spec
+from gym.envs import make, spec, register
 from gym import logger
 
-__all__ = ["Env", "Space", "Wrapper", "make", "spec"]
+__all__ = ["Env", "Space", "Wrapper", "make", "spec", "register"]
diff --git a/gym/envs/registration.py b/gym/envs/registration.py
index 16b99dbbfab..6b51f153b16 100644
--- a/gym/envs/registration.py
+++ b/gym/envs/registration.py
@@ -74,16 +74,17 @@ def __init__(self, id, entry_point=None, trials=100, reward_threshold=None, loca
         self._local_only = local_only
         self._kwargs = {} if kwargs is None else kwargs
 
-    def make(self):
+    def make(self, **kwargs):
         """Instantiates an instance of the environment with appropriate kwargs"""
         if self._entry_point is None:
             raise error.Error('Attempting to make deprecated env {}. (HINT: is there a newer registered version of this env?)'.format(self.id))
-
-        elif callable(self._entry_point):
-            env = self._entry_point(**self._kwargs)
+        _kwargs = self._kwargs.copy()
+        _kwargs.update(kwargs)
+        if callable(self._entry_point):
+            env = self._entry_point(**_kwargs)
         else:
             cls = load(self._entry_point)
-            env = cls(**self._kwargs)
+            env = cls(**_kwargs)
 
         # Make the enviroment aware of which spec it came from.
         env.unwrapped.spec = self
@@ -113,10 +114,13 @@ class EnvRegistry(object):
     def __init__(self):
         self.env_specs = {}
 
-    def make(self, id):
-        logger.info('Making new env: %s', id)
+    def make(self, id, **kwargs):
+        if len(kwargs) > 0:
+            logger.info('Making new env: %s (%s)', id, kwargs)
+        else:
+            logger.info('Making new env: %s', id)
         spec = self.spec(id)
-        env = spec.make()
+        env = spec.make(**kwargs)
         # We used to have people override _reset/_step rather than
         # reset/step. Set _gym_disable_underscore_compat = True on
         # your environment if you use these methods and don't want
@@ -163,8 +167,8 @@ def register(self, id, **kwargs):
 def register(id, **kwargs):
     return registry.register(id, **kwargs)
 
-def make(id):
-    return registry.make(id)
+def make(id, **kwargs):
+    return registry.make(id, **kwargs)
 
 def spec(id):
     return registry.spec(id)
diff --git a/gym/envs/tests/test_registration.py b/gym/envs/tests/test_registration.py
index a7990bb3b16..e8e60331f37 100644
--- a/gym/envs/tests/test_registration.py
+++ b/gym/envs/tests/test_registration.py
@@ -1,13 +1,37 @@
 # -*- coding: utf-8 -*-
+import gym
 from gym import error, envs
 from gym.envs import registration
 from gym.envs.classic_control import cartpole
 
+class ArgumentEnv(gym.Env):
+    def __init__(self, arg1, arg2, arg3):
+        self.arg1 = arg1
+        self.arg2 = arg2
+        self.arg3 = arg3
+
+gym.register(
+    id='test.ArgumentEnv-v0',
+    entry_point='gym.envs.tests.test_registration:ArgumentEnv',
+    kwargs={
+        'arg1': 'arg1',
+        'arg2': 'arg2',
+    }
+)
+
 def test_make():
     env = envs.make('CartPole-v0')
     assert env.spec.id == 'CartPole-v0'
     assert isinstance(env.unwrapped, cartpole.CartPoleEnv)
 
+def test_make_with_kwargs():
+    env = envs.make('test.ArgumentEnv-v0', arg2='override_arg2', arg3='override_arg3')
+    assert env.spec.id == 'test.ArgumentEnv-v0'
+    assert isinstance(env.unwrapped, ArgumentEnv)
+    assert env.arg1 == 'arg1'
+    assert env.arg2 == 'override_arg2'
+    assert env.arg3 == 'override_arg3'
+
 def test_make_deprecated():
     try:
         envs.make('Humanoid-v0')

We avoided adding kwargs for a long time in order to encourage people to statically register their environment definitions. However, over time we've found a few important use-cases for kwargs, such as:

- Runtime-specific objects, such as which GPU to run the environment on
- Parametrized environments, which can have an infinite number of meaningful variants

The latter breaks the invariant that the environment ID alone determines the semantics of the environment, but it's an advanced use-case and such users should be able to manage this on their own.

This PR also exports the `register` method so people can register their own environments more easily.