Repository: openai/gym

Issue:
[Bug Report] Box bounded below and above doesn't work when dtype is int
**Describe the bug**
A `Box` space that is created with dtype `int` and `low` (`high`) values being `-np.inf` (`np.inf`) will return `bounded_{above,below}` as True.

**Code example**
```python3
from gym.spaces import Box
import numpy as np

unbounded_below = Box(
    np.array([0, 13, -3, -np.inf]),
    np.array([0, 20, 0, 0]),
    dtype=int
)

unbounded_above = Box(
    np.array([0, 12, 20, 0]),
    np.array([np.inf, 20, 24, np.inf]),
    dtype=int
)

print(unbounded_above.bounded_above)
print(unbounded_below.bounded_below)

>>> [ True  True  True  True]
>>> [ True  True  True  True]
```

**My analysis**
At the [broadcast](https://github.com/openai/gym/blob/master/gym/spaces/box.py#L64), [get_inf](https://github.com/openai/gym/blob/master/gym/spaces/box.py#L226) turns `np.inf` into their integer equivalents. Determining [boundedness](https://github.com/openai/gym/blob/master/gym/spaces/box.py#L86) is comparing directly with `np.inf`, not with the integer equivalents given from `get_inf`.

**System Info**
Describe the characteristic of your environment:
 * Gym installed with pip
 * MacOS 10.15.7
 * Python version: 3.7.9
 * numpy 1.21.5

**Additional context**
I know it may seem strange to use `np.inf` with an integer-Box, but I use integer-Boxes all the time, and I need to check against `np.inf`.

### Checklist

- [X] I have checked that there is no similar [issue](https://github.com/openai/gym/issues) in the repo (**required**)



Discussion:

Resolving patch:
diff --git a/gym/spaces/box.py b/gym/spaces/box.py
--- a/gym/spaces/box.py
+++ b/gym/spaces/box.py
@@ -61,8 +61,14 @@ def __init__(
             )
         assert isinstance(shape, tuple)
 
+        # Capture the boundedness information before replacing np.inf with get_inf
+        _low = np.full(shape, low, dtype=float) if np.isscalar(low) else low
+        self.bounded_below = -np.inf < _low
+        _high = np.full(shape, high, dtype=float) if np.isscalar(high) else high
+        self.bounded_above = np.inf > _high
+
         low = _broadcast(low, dtype, shape, inf_sign="-")  # type: ignore
-        high = _broadcast(high, dtype, shape, inf_sign="+")
+        high = _broadcast(high, dtype, shape, inf_sign="+")  # type: ignore
 
         assert isinstance(low, np.ndarray)
         assert low.shape == shape, "low.shape doesn't match provided shape"
@@ -82,10 +88,6 @@ def __init__(
         self.low_repr = _short_repr(self.low)
         self.high_repr = _short_repr(self.high)
 
-        # Boolean arrays which indicate the interval type for each coordinate
-        self.bounded_below = -np.inf < self.low
-        self.bounded_above = np.inf > self.high
-
         super().__init__(self.shape, self.dtype, seed)
 
     @property


Test patch:
diff --git a/tests/spaces/test_spaces.py b/tests/spaces/test_spaces.py
--- a/tests/spaces/test_spaces.py
+++ b/tests/spaces/test_spaces.py
@@ -508,29 +508,23 @@ def test_infinite_space(space):
 
     # check that int bounds are bounded for everything
     # but floats are unbounded for infinite
-    if space.dtype.kind == "f":
-        if np.any(space.high != 0):
-            assert (
-                space.is_bounded("above") == False
-            ), "float dtype inf upper bound supposed to be unbounded"
-        else:
-            assert (
-                space.is_bounded("above") == True
-            ), "float dtype non-inf upper bound supposed to be bounded"
-
-        if np.any(space.low != 0):
-            assert (
-                space.is_bounded("below") == False
-            ), "float dtype inf lower bound supposed to be unbounded"
-        else:
-            assert (
-                space.is_bounded("below") == True
-            ), "float dtype non-inf lower bound supposed to be bounded"
+    if np.any(space.high != 0):
+        assert (
+            space.is_bounded("above") == False
+        ), "inf upper bound supposed to be unbounded"
+    else:
+        assert (
+            space.is_bounded("above") == True
+        ), "non-inf upper bound supposed to be bounded"
 
-    elif space.dtype.kind == "i":
+    if np.any(space.low != 0):
+        assert (
+            space.is_bounded("below") == False
+        ), "inf lower bound supposed to be unbounded"
+    else:
         assert (
-            space.is_bounded("both") == True
-        ), "int dtypes should be bounded on both ends"
+            space.is_bounded("below") == True
+        ), "non-inf lower bound supposed to be bounded"
 
     # check for dtype
     assert (