| # Copyright (c) 2010-2017 Benjamin Peterson |
| # |
| # Permission is hereby granted, free of charge, to any person obtaining a copy |
| # of this software and associated documentation files (the "Software"), to deal |
| # in the Software without restriction, including without limitation the rights |
| # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| # copies of the Software, and to permit persons to whom the Software is |
| # furnished to do so, subject to the following conditions: |
| # |
| # The above copyright notice and this permission notice shall be included in all |
| # copies or substantial portions of the Software. |
| # |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| # SOFTWARE. |
| |
| import builtins |
| import collections.abc |
| import io |
| import math |
| import sys |
| import types |
| import queue # noqa: F401 |
| |
| inf = math.inf |
| nan = math.nan |
| string_classes = (str, bytes) |
| int_classes = int |
| FileNotFoundError = builtins.FileNotFoundError |
| StringIO = io.StringIO |
| container_abcs = collections.abc |
| PY3 = sys.version_info[0] == 3 |
| PY37 = sys.version_info[0] == 3 and sys.version_info[1] >= 7 |
| |
| def with_metaclass(meta: type, *bases) -> type: |
| """Create a base class with a metaclass.""" |
| # This requires a bit of explanation: the basic idea is to make a dummy |
| # metaclass for one level of class instantiation that replaces itself with |
| # the actual metaclass. |
| class metaclass(meta): # type: ignore[misc, valid-type] |
| |
| def __new__(cls, name, this_bases, d): |
| return meta(name, bases, d) |
| |
| @classmethod |
| def __prepare__(cls, name, this_bases): |
| return meta.__prepare__(name, bases) |
| |
| return type.__new__(metaclass, 'temporary_class', (), {}) |
| |
| |
| # Gets a function from the name of a method on a type |
| def get_function_from_type(cls, name): |
| return getattr(cls, name, None) |
| |
| |
| # The codes below is not copied from the six package, so the copyright |
| # declaration at the beginning does not apply. |
| # |
| # Copyright(c) PyTorch contributors |
| # |
| |
| def istuple(obj) -> bool: |
| # Usually instances of PyStructSequence is also an instance of tuple |
| # but in some py2 environment it is not, so we have to manually check |
| # the name of the type to determine if it is a namedtupled returned |
| # by a pytorch operator. |
| t = type(obj) |
| return isinstance(obj, tuple) or t.__module__ == 'torch.return_types' |
| |
| def bind_method(fn, obj, obj_type): |
| return types.MethodType(fn, obj) |