File: uid.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (61 lines) | stat: -rw-r--r-- 1,855 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import math
import struct

HUGEVAL_BYTES = struct.calcsize('P')
HUGEVAL = 256 ** HUGEVAL_BYTES


def fixid(result):
    if result < 0:
        result += HUGEVAL
    return result

uid = id    # guaranteed to be positive from CPython 2.5 onwards


class Hashable(object):
    """
    A Hashable instance encapsulates any object, but is always usable as a
    key in dictionaries.  This is based on id() for mutable objects and on
    real hash/compare for immutable ones.
    """
    __slots__ = ["key", "value"]

    def __init__(self, value):
        self.value = value     # a concrete value
        # try to be smart about constant mutable or immutable values
        key = type(self.value), self.value  # to avoid confusing e.g. 0 and 0.0
        #
        # we also have to avoid confusing 0.0 and -0.0 (needed e.g. for
        # translating the cmath module)
        if key[0] is float and not self.value:
            if math.copysign(1., self.value) == -1.:    # -0.0
                key = (float, "-0.0")
        #
        try:
            hash(key)
        except TypeError:
            key = id(self.value)
        self.key = key

    def __eq__(self, other):
        return self.__class__ is other.__class__ and self.key == other.key

    def __ne__(self, other):
        return not (self == other)

    def __hash__(self):
        return hash(self.key)

    def __repr__(self):
        return '(%s)' % (self,)

    def __str__(self):
        # try to limit the size of the repr to make it more readable
        r = repr(self.value)
        if (r.startswith('<') and r.endswith('>') and
                hasattr(self.value, '__name__')):
            r = '%s %s' % (type(self.value).__name__, self.value.__name__)
        elif len(r) > 60 or (len(r) > 30 and type(self.value) is not str):
            r = r[:22] + '...' + r[-7:]
        return r