def __init__(self, env_fns, spaces=None):
if spaces:<EOL><INDENT>observation_space, action_space = spaces<EOL><DEDENT>else:<EOL><INDENT>logger.log('<STR_LIT>')<EOL>with logger.scoped_configure(format_strs=[]):<EOL><INDENT>dummy = env_fns[<NUM_LIT:0>]()<EOL>observation_space, action_space = dummy.observation_space, dummy.action_space<EOL>dummy.close()<EOL>del dummy<EOL><DEDENT><DEDENT>VecEnv.__init__(self, len(env_fns), observation_space, action_space)<EOL>self.obs_keys, self.obs_shapes, self.obs_dtypes = obs_space_info(observation_space)<EOL>self.obs_bufs = [<EOL>{k: Array(_NP_TO_CT[self.obs_dtypes[k].type], int(np.prod(self.obs_shapes[k]))) for k in self.obs_keys}<EOL>for _ in env_fns]<EOL>self.parent_pipes = []<EOL>self.procs = []<EOL>for env_fn, obs_buf in zip(env_fns, self.obs_bufs):<EOL><INDENT>wrapped_fn = CloudpickleWrapper(env_fn)<EOL>parent_pipe, child_pipe = Pipe()<EOL>proc = Process(target=_subproc_worker,<EOL>args=(child_pipe, parent_pipe, wrapped_fn, obs_buf, self.obs_shapes, self.obs_dtypes, self.obs_keys))<EOL>proc.daemon = True<EOL>self.procs.append(proc)<EOL>self.parent_pipes.append(parent_pipe)<EOL>proc.start()<EOL>child_pipe.close()<EOL><DEDENT>self.waiting_step = False<EOL>self.specs = [f().spec for f in env_fns]<EOL>self.viewer = None<EOL>
If you don't specify observation_space, we'll have to create a dummy
environment to get it.