1try:
2    from collections.abc import Iterable
3except ImportError:
4    Iterable = (tuple, list)
5
6from gym.vector.async_vector_env import AsyncVectorEnv
7from gym.vector.sync_vector_env import SyncVectorEnv
8from gym.vector.vector_env import VectorEnv, VectorEnvWrapper
9
10__all__ = ["AsyncVectorEnv", "SyncVectorEnv", "VectorEnv", "VectorEnvWrapper", "make"]
11
12
13def make(id, num_envs=1, asynchronous=True, wrappers=None, **kwargs):
14    """Create a vectorized environment from multiple copies of an environment,
15    from its id
16
17    Parameters
18    ----------
19    id : str
20        The environment ID. This must be a valid ID from the registry.
21
22    num_envs : int
23        Number of copies of the environment.
24
25    asynchronous : bool (default: `True`)
26        If `True`, wraps the environments in an `AsyncVectorEnv` (which uses
27        `multiprocessing` to run the environments in parallel). If `False`,
28        wraps the environments in a `SyncVectorEnv`.
29
30    wrappers : Callable or Iterable of Callables (default: `None`)
31        If not `None`, then apply the wrappers to each internal
32        environment during creation.
33
34    Returns
35    -------
36    env : `gym.vector.VectorEnv` instance
37        The vectorized environment.
38
39    Example
40    -------
41    >>> import gym
42    >>> env = gym.vector.make('CartPole-v1', 3)
43    >>> env.reset()
44    array([[-0.04456399,  0.04653909,  0.01326909, -0.02099827],
45           [ 0.03073904,  0.00145001, -0.03088818, -0.03131252],
46           [ 0.03468829,  0.01500225,  0.01230312,  0.01825218]],
47          dtype=float32)
48    """
49    from gym.envs import make as make_
50
51    def _make_env():
52        env = make_(id, **kwargs)
53        if wrappers is not None:
54            if callable(wrappers):
55                env = wrappers(env)
56            elif isinstance(wrappers, Iterable) and all(
57                [callable(w) for w in wrappers]
58            ):
59                for wrapper in wrappers:
60                    env = wrapper(env)
61            else:
62                raise NotImplementedError
63        return env
64
65    env_fns = [_make_env for _ in range(num_envs)]
66    return AsyncVectorEnv(env_fns) if asynchronous else SyncVectorEnv(env_fns)
67