mirror of
				https://github.com/sqlmapproject/sqlmap.git
				synced 2025-11-04 01:47:37 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			477 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			477 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#!/usr/bin/env python
 | 
						|
# -*- mode:python; tab-width: 2; coding: utf-8 -*-
 | 
						|
 | 
						|
"""Partially backported python ABC classes"""
 | 
						|
 | 
						|
from __future__ import absolute_import
 | 
						|
 | 
						|
import sys
 | 
						|
import types
 | 
						|
 | 
						|
if sys.version_info > (2, 6):
 | 
						|
    raise ImportError("Use native ABC classes istead of this one.")
 | 
						|
 | 
						|
 | 
						|
# Instance of old-style class
 | 
						|
class _C:
 | 
						|
    pass
 | 
						|
 | 
						|
_InstanceType = type(_C())
 | 
						|
 | 
						|
 | 
						|
def abstractmethod(funcobj):
 | 
						|
    """A decorator indicating abstract methods.
 | 
						|
 | 
						|
    Requires that the metaclass is ABCMeta or derived from it.  A
 | 
						|
    class that has a metaclass derived from ABCMeta cannot be
 | 
						|
    instantiated unless all of its abstract methods are overridden.
 | 
						|
    The abstract methods can be called using any of the normal
 | 
						|
    'super' call mechanisms.
 | 
						|
 | 
						|
    Usage:
 | 
						|
 | 
						|
        class C:
 | 
						|
            __metaclass__ = ABCMeta
 | 
						|
            @abstractmethod
 | 
						|
            def my_abstract_method(self, ...):
 | 
						|
                ...
 | 
						|
    """
 | 
						|
    funcobj.__isabstractmethod__ = True
 | 
						|
    return funcobj
 | 
						|
 | 
						|
 | 
						|
class ABCMeta(type):
 | 
						|
 | 
						|
    """Metaclass for defining Abstract Base Classes (ABCs).
 | 
						|
 | 
						|
    Use this metaclass to create an ABC.  An ABC can be subclassed
 | 
						|
    directly, and then acts as a mix-in class.  You can also register
 | 
						|
    unrelated concrete classes (even built-in classes) and unrelated
 | 
						|
    ABCs as 'virtual subclasses' -- these and their descendants will
 | 
						|
    be considered subclasses of the registering ABC by the built-in
 | 
						|
    issubclass() function, but the registering ABC won't show up in
 | 
						|
    their MRO (Method Resolution Order) nor will method
 | 
						|
    implementations defined by the registering ABC be callable (not
 | 
						|
    even via super()).
 | 
						|
 | 
						|
    """
 | 
						|
 | 
						|
    # A global counter that is incremented each time a class is
 | 
						|
    # registered as a virtual subclass of anything.  It forces the
 | 
						|
    # negative cache to be cleared before its next use.
 | 
						|
    _abc_invalidation_counter = 0
 | 
						|
 | 
						|
    def __new__(mcls, name, bases, namespace):
 | 
						|
        cls = super(ABCMeta, mcls).__new__(mcls, name, bases, namespace)
 | 
						|
        # Compute set of abstract method names
 | 
						|
        abstracts = set(name
 | 
						|
                     for name, value in namespace.items()
 | 
						|
                     if getattr(value, "__isabstractmethod__", False))
 | 
						|
        for base in bases:
 | 
						|
            for name in getattr(base, "__abstractmethods__", set()):
 | 
						|
                value = getattr(cls, name, None)
 | 
						|
                if getattr(value, "__isabstractmethod__", False):
 | 
						|
                    abstracts.add(name)
 | 
						|
        cls.__abstractmethods__ = frozenset(abstracts)
 | 
						|
        # Set up inheritance registry
 | 
						|
        cls._abc_registry = set()
 | 
						|
        cls._abc_cache = set()
 | 
						|
        cls._abc_negative_cache = set()
 | 
						|
        cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
 | 
						|
        return cls
 | 
						|
 | 
						|
    def register(cls, subclass):
 | 
						|
        """Register a virtual subclass of an ABC."""
 | 
						|
        if not isinstance(subclass, (type, types.ClassType)):
 | 
						|
            raise TypeError("Can only register classes")
 | 
						|
        if issubclass(subclass, cls):
 | 
						|
            return  # Already a subclass
 | 
						|
        # Subtle: test for cycles *after* testing for "already a subclass";
 | 
						|
        # this means we allow X.register(X) and interpret it as a no-op.
 | 
						|
        if issubclass(cls, subclass):
 | 
						|
            # This would create a cycle, which is bad for the algorithm below
 | 
						|
            raise RuntimeError("Refusing to create an inheritance cycle")
 | 
						|
        cls._abc_registry.add(subclass)
 | 
						|
        ABCMeta._abc_invalidation_counter += 1  # Invalidate negative cache
 | 
						|
 | 
						|
    def _dump_registry(cls, file=None):
 | 
						|
        """Debug helper to print the ABC registry."""
 | 
						|
        print >> file, "Class: %s.%s" % (cls.__module__, cls.__name__)
 | 
						|
        print >> file, "Inv.counter: %s" % ABCMeta._abc_invalidation_counter
 | 
						|
        for name in sorted(cls.__dict__.keys()):
 | 
						|
            if name.startswith("_abc_"):
 | 
						|
                value = getattr(cls, name)
 | 
						|
                print >> file, "%s: %r" % (name, value)
 | 
						|
 | 
						|
    def __instancecheck__(cls, instance):
 | 
						|
        """Override for isinstance(instance, cls)."""
 | 
						|
        # Inline the cache checking when it's simple.
 | 
						|
        subclass = getattr(instance, '__class__', None)
 | 
						|
        if subclass in cls._abc_cache:
 | 
						|
            return True
 | 
						|
        subtype = type(instance)
 | 
						|
        # Old-style instances
 | 
						|
        if subtype is _InstanceType:
 | 
						|
            subtype = subclass
 | 
						|
        if subtype is subclass or subclass is None:
 | 
						|
            if (cls._abc_negative_cache_version ==
 | 
						|
                ABCMeta._abc_invalidation_counter and
 | 
						|
                subtype in cls._abc_negative_cache):
 | 
						|
                return False
 | 
						|
            # Fall back to the subclass check.
 | 
						|
            return cls.__subclasscheck__(subtype)
 | 
						|
        return (cls.__subclasscheck__(subclass) or
 | 
						|
                cls.__subclasscheck__(subtype))
 | 
						|
 | 
						|
    def __subclasscheck__(cls, subclass):
 | 
						|
        """Override for issubclass(subclass, cls)."""
 | 
						|
        # Check cache
 | 
						|
        if subclass in cls._abc_cache:
 | 
						|
            return True
 | 
						|
        # Check negative cache; may have to invalidate
 | 
						|
        if cls._abc_negative_cache_version < ABCMeta._abc_invalidation_counter:
 | 
						|
            # Invalidate the negative cache
 | 
						|
            cls._abc_negative_cache = set()
 | 
						|
            cls._abc_negative_cache_version = ABCMeta._abc_invalidation_counter
 | 
						|
        elif subclass in cls._abc_negative_cache:
 | 
						|
            return False
 | 
						|
        # Check the subclass hook
 | 
						|
        ok = cls.__subclasshook__(subclass)
 | 
						|
        if ok is not NotImplemented:
 | 
						|
            assert isinstance(ok, bool)
 | 
						|
            if ok:
 | 
						|
                cls._abc_cache.add(subclass)
 | 
						|
            else:
 | 
						|
                cls._abc_negative_cache.add(subclass)
 | 
						|
            return ok
 | 
						|
        # Check if it's a direct subclass
 | 
						|
        if cls in getattr(subclass, '__mro__', ()):
 | 
						|
            cls._abc_cache.add(subclass)
 | 
						|
            return True
 | 
						|
        # Check if it's a subclass of a registered class (recursive)
 | 
						|
        for rcls in cls._abc_registry:
 | 
						|
            if issubclass(subclass, rcls):
 | 
						|
                cls._abc_cache.add(subclass)
 | 
						|
                return True
 | 
						|
        # Check if it's a subclass of a subclass (recursive)
 | 
						|
        for scls in cls.__subclasses__():
 | 
						|
            if issubclass(subclass, scls):
 | 
						|
                cls._abc_cache.add(subclass)
 | 
						|
                return True
 | 
						|
        # No dice; update negative cache
 | 
						|
        cls._abc_negative_cache.add(subclass)
 | 
						|
        return False
 | 
						|
 | 
						|
 | 
						|
def _hasattr(C, attr):
 | 
						|
    try:
 | 
						|
        return any(attr in B.__dict__ for B in C.__mro__)
 | 
						|
    except AttributeError:
 | 
						|
        # Old-style class
 | 
						|
        return hasattr(C, attr)
 | 
						|
 | 
						|
 | 
						|
class Sized:
 | 
						|
    __metaclass__ = ABCMeta
 | 
						|
 | 
						|
    @abstractmethod
 | 
						|
    def __len__(self):
 | 
						|
        return 0
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def __subclasshook__(cls, C):
 | 
						|
        if cls is Sized:
 | 
						|
            if _hasattr(C, "__len__"):
 | 
						|
                return True
 | 
						|
        return NotImplemented
 | 
						|
 | 
						|
 | 
						|
class Container:
 | 
						|
    __metaclass__ = ABCMeta
 | 
						|
 | 
						|
    @abstractmethod
 | 
						|
    def __contains__(self, x):
 | 
						|
        return False
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def __subclasshook__(cls, C):
 | 
						|
        if cls is Container:
 | 
						|
            if _hasattr(C, "__contains__"):
 | 
						|
                return True
 | 
						|
        return NotImplemented
 | 
						|
 | 
						|
 | 
						|
class Iterable:
 | 
						|
    __metaclass__ = ABCMeta
 | 
						|
 | 
						|
    @abstractmethod
 | 
						|
    def __iter__(self):
 | 
						|
        while False:
 | 
						|
            yield None
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def __subclasshook__(cls, C):
 | 
						|
        if cls is Iterable:
 | 
						|
            if _hasattr(C, "__iter__"):
 | 
						|
                return True
 | 
						|
        return NotImplemented
 | 
						|
 | 
						|
Iterable.register(str)
 | 
						|
 | 
						|
 | 
						|
class Set(Sized, Iterable, Container):
 | 
						|
    """A set is a finite, iterable container.
 | 
						|
 | 
						|
    This class provides concrete generic implementations of all
 | 
						|
    methods except for __contains__, __iter__ and __len__.
 | 
						|
 | 
						|
    To override the comparisons (presumably for speed, as the
 | 
						|
    semantics are fixed), all you have to do is redefine __le__ and
 | 
						|
    then the other operations will automatically follow suit.
 | 
						|
    """
 | 
						|
 | 
						|
    def __le__(self, other):
 | 
						|
        if not isinstance(other, Set):
 | 
						|
            return NotImplemented
 | 
						|
        if len(self) > len(other):
 | 
						|
            return False
 | 
						|
        for elem in self:
 | 
						|
            if elem not in other:
 | 
						|
                return False
 | 
						|
        return True
 | 
						|
 | 
						|
    def __lt__(self, other):
 | 
						|
        if not isinstance(other, Set):
 | 
						|
            return NotImplemented
 | 
						|
        return len(self) < len(other) and self.__le__(other)
 | 
						|
 | 
						|
    def __gt__(self, other):
 | 
						|
        if not isinstance(other, Set):
 | 
						|
            return NotImplemented
 | 
						|
        return other < self
 | 
						|
 | 
						|
    def __ge__(self, other):
 | 
						|
        if not isinstance(other, Set):
 | 
						|
            return NotImplemented
 | 
						|
        return other <= self
 | 
						|
 | 
						|
    def __eq__(self, other):
 | 
						|
        if not isinstance(other, Set):
 | 
						|
            return NotImplemented
 | 
						|
        return len(self) == len(other) and self.__le__(other)
 | 
						|
 | 
						|
    def __ne__(self, other):
 | 
						|
        return not (self == other)
 | 
						|
 | 
						|
    @classmethod
 | 
						|
    def _from_iterable(cls, it):
 | 
						|
        '''Construct an instance of the class from any iterable input.
 | 
						|
 | 
						|
        Must override this method if the class constructor signature
 | 
						|
        does not accept an iterable for an input.
 | 
						|
        '''
 | 
						|
        return cls(it)
 | 
						|
 | 
						|
    def __and__(self, other):
 | 
						|
        if not isinstance(other, Iterable):
 | 
						|
            return NotImplemented
 | 
						|
        return self._from_iterable(value for value in other if value in self)
 | 
						|
 | 
						|
    def isdisjoint(self, other):
 | 
						|
        for value in other:
 | 
						|
            if value in self:
 | 
						|
                return False
 | 
						|
        return True
 | 
						|
 | 
						|
    def __or__(self, other):
 | 
						|
        if not isinstance(other, Iterable):
 | 
						|
            return NotImplemented
 | 
						|
        chain = (e for s in (self, other) for e in s)
 | 
						|
        return self._from_iterable(chain)
 | 
						|
 | 
						|
    def __sub__(self, other):
 | 
						|
        if not isinstance(other, Set):
 | 
						|
            if not isinstance(other, Iterable):
 | 
						|
                return NotImplemented
 | 
						|
            other = self._from_iterable(other)
 | 
						|
        return self._from_iterable(value for value in self
 | 
						|
                                   if value not in other)
 | 
						|
 | 
						|
    def __xor__(self, other):
 | 
						|
        if not isinstance(other, Set):
 | 
						|
            if not isinstance(other, Iterable):
 | 
						|
                return NotImplemented
 | 
						|
            other = self._from_iterable(other)
 | 
						|
        return (self - other) | (other - self)
 | 
						|
 | 
						|
    # Sets are not hashable by default, but subclasses can change this
 | 
						|
    __hash__ = None
 | 
						|
 | 
						|
    def _hash(self):
 | 
						|
        """Compute the hash value of a set.
 | 
						|
 | 
						|
        Note that we don't define __hash__: not all sets are hashable.
 | 
						|
        But if you define a hashable set type, its __hash__ should
 | 
						|
        call this function.
 | 
						|
 | 
						|
        This must be compatible __eq__.
 | 
						|
 | 
						|
        All sets ought to compare equal if they contain the same
 | 
						|
        elements, regardless of how they are implemented, and
 | 
						|
        regardless of the order of the elements; so there's not much
 | 
						|
        freedom for __eq__ or __hash__.  We match the algorithm used
 | 
						|
        by the built-in frozenset type.
 | 
						|
        """
 | 
						|
        MAX = sys.maxint
 | 
						|
        MASK = 2 * MAX + 1
 | 
						|
        n = len(self)
 | 
						|
        h = 1927868237 * (n + 1)
 | 
						|
        h &= MASK
 | 
						|
        for x in self:
 | 
						|
            hx = hash(x)
 | 
						|
            h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167
 | 
						|
            h &= MASK
 | 
						|
        h = h * 69069 + 907133923
 | 
						|
        h &= MASK
 | 
						|
        if h > MAX:
 | 
						|
            h -= MASK + 1
 | 
						|
        if h == -1:
 | 
						|
            h = 590923713
 | 
						|
        return h
 | 
						|
 | 
						|
Set.register(frozenset)
 | 
						|
 | 
						|
 | 
						|
class MutableSet(Set):
 | 
						|
 | 
						|
    @abstractmethod
 | 
						|
    def add(self, value):
 | 
						|
        """Add an element."""
 | 
						|
        raise NotImplementedError
 | 
						|
 | 
						|
    @abstractmethod
 | 
						|
    def discard(self, value):
 | 
						|
        """Remove an element.  Do not raise an exception if absent."""
 | 
						|
        raise NotImplementedError
 | 
						|
 | 
						|
    def remove(self, value):
 | 
						|
        """Remove an element. If not a member, raise a KeyError."""
 | 
						|
        if value not in self:
 | 
						|
            raise KeyError(value)
 | 
						|
        self.discard(value)
 | 
						|
 | 
						|
    def pop(self):
 | 
						|
        """Return the popped value.  Raise KeyError if empty."""
 | 
						|
        it = iter(self)
 | 
						|
        try:
 | 
						|
            value = it.next()
 | 
						|
        except StopIteration:
 | 
						|
            raise KeyError
 | 
						|
        self.discard(value)
 | 
						|
        return value
 | 
						|
 | 
						|
    def clear(self):
 | 
						|
        """This is slow (creates N new iterators!) but effective."""
 | 
						|
        try:
 | 
						|
            while True:
 | 
						|
                self.pop()
 | 
						|
        except KeyError:
 | 
						|
            pass
 | 
						|
 | 
						|
    def __ior__(self, it):
 | 
						|
        for value in it:
 | 
						|
            self.add(value)
 | 
						|
        return self
 | 
						|
 | 
						|
    def __iand__(self, it):
 | 
						|
        for value in (self - it):
 | 
						|
            self.discard(value)
 | 
						|
        return self
 | 
						|
 | 
						|
    def __ixor__(self, it):
 | 
						|
        if not isinstance(it, Set):
 | 
						|
            it = self._from_iterable(it)
 | 
						|
        for value in it:
 | 
						|
            if value in self:
 | 
						|
                self.discard(value)
 | 
						|
            else:
 | 
						|
                self.add(value)
 | 
						|
        return self
 | 
						|
 | 
						|
    def __isub__(self, it):
 | 
						|
        for value in it:
 | 
						|
            self.discard(value)
 | 
						|
        return self
 | 
						|
 | 
						|
MutableSet.register(set)
 | 
						|
 | 
						|
 | 
						|
class OrderedSet(MutableSet):
 | 
						|
 | 
						|
    def __init__(self, iterable=None):
 | 
						|
        self.end = end = []
 | 
						|
        end += [None, end, end]         # sentinel node for doubly linked list
 | 
						|
        self.map = {}                   # key --> [key, prev, next]
 | 
						|
        if iterable is not None:
 | 
						|
            self |= iterable
 | 
						|
 | 
						|
    def __len__(self):
 | 
						|
        return len(self.map)
 | 
						|
 | 
						|
    def __contains__(self, key):
 | 
						|
        return key in self.map
 | 
						|
 | 
						|
    def __getitem__(self, key):
 | 
						|
        return list(self)[key]
 | 
						|
 | 
						|
    def add(self, key):
 | 
						|
        if key not in self.map:
 | 
						|
            end = self.end
 | 
						|
            curr = end[PREV]
 | 
						|
            curr[NEXT] = end[PREV] = self.map[key] = [key, curr, end]
 | 
						|
 | 
						|
    def discard(self, key):
 | 
						|
        if key in self.map:
 | 
						|
            key, prev, next = self.map.pop(key)
 | 
						|
            prev[NEXT] = next
 | 
						|
            next[PREV] = prev
 | 
						|
 | 
						|
    def __iter__(self):
 | 
						|
        end = self.end
 | 
						|
        curr = end[NEXT]
 | 
						|
        while curr is not end:
 | 
						|
            yield curr[KEY]
 | 
						|
            curr = curr[NEXT]
 | 
						|
 | 
						|
    def __reversed__(self):
 | 
						|
        end = self.end
 | 
						|
        curr = end[PREV]
 | 
						|
        while curr is not end:
 | 
						|
            yield curr[KEY]
 | 
						|
            curr = curr[PREV]
 | 
						|
 | 
						|
    def pop(self, last=True):
 | 
						|
        if not self:
 | 
						|
            raise KeyError('set is empty')
 | 
						|
        key = reversed(self).next() if last else iter(self).next()
 | 
						|
        self.discard(key)
 | 
						|
        return key
 | 
						|
 | 
						|
    def __repr__(self):
 | 
						|
        if not self:
 | 
						|
            return '%s()' % (self.__class__.__name__,)
 | 
						|
        return '%s(%r)' % (self.__class__.__name__, list(self))
 | 
						|
 | 
						|
    def __eq__(self, other):
 | 
						|
        if isinstance(other, OrderedSet):
 | 
						|
            return len(self) == len(other) and list(self) == list(other)
 | 
						|
        return set(self) == set(other)
 | 
						|
 | 
						|
    def __del__(self):
 | 
						|
        if all([KEY, PREV, NEXT]):
 | 
						|
            self.clear()                    # remove circular references
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    print(OrderedSet('abracadaba'))
 | 
						|
    print(OrderedSet('simsalabim'))
 |