Exemplo n.º 1
0
 def test_consistency(self):
     from random import randint
     from xoutil.eight import range
     from xoutil.collections import BitPascalSet
     count = 5
     for test in range(count):
         size = randint(20, 60)
         ranges = (range(i, randint(i, i + 3)) for i in range(1, size))
         s1 = BitPascalSet(*ranges)
         ranges = (range(i, randint(i, i + 3)) for i in range(1, size))
         s2 = BitPascalSet(*ranges)
         ss1 = set(s1)
         ss2 = set(s2)
         self.assertEqual(s1, ss1)
         self.assertEqual(s1 - s2, ss1 - ss2)
         self.assertEqual(s2 - s1, ss2 - ss1)
         self.assertEqual(s1 & s2, ss1 & ss2)
         self.assertEqual(s2 & s1, ss2 & ss1)
         self.assertEqual(s1 | s2, ss1 | ss2)
         self.assertEqual(s2 | s1, ss2 | ss1)
         self.assertEqual(s1 ^ s2, ss1 ^ ss2)
         self.assertEqual(s2 ^ s1, ss2 ^ ss1)
         self.assertLess(s1 - s2, s1)
         self.assertLess(s1 - s2, ss1)
         self.assertLessEqual(s1 - s2, s1)
         self.assertLessEqual(s1 - s2, ss1)
         self.assertGreater(s1, s1 - s2)
         self.assertGreater(s1, ss1 - ss2)
         self.assertGreaterEqual(s1, s1 - s2)
         self.assertGreaterEqual(s1, ss1 - ss2)
Exemplo n.º 2
0
    def addRule(self, doc, func, _preprocess=1):
        doc = self.strip_comments(doc)
        fn = func
        rules = doc.split()

        # First, detect all lines where a new production is given.
        index = []
        for i in range(len(rules)):
            if rules[i] == '::=':
                index.append(i-1)
        index.append(len(rules))

        # Now process each rule add it the rules.  We take care of making of
        # splitting right hand sides with vertical bars into several rules.
        for i in range(len(index)-1):
            lhs = rules[index[i]]
            rhss = rules[index[i]+2:index[i+1]]
            lhs_rules = self.rules.setdefault(lhs, [])
            for rhs in iter_rhss(rhss):
                rule = (lhs, tuple(rhs))
                if _preprocess:
                    rule, fn = self.preprocess(rule, func)
                lhs_rules.append(rule)
                self.rule2func[rule] = fn
                self.rule2name[rule] = func.__name__[2:]
        self.ruleschanged = 1
Exemplo n.º 3
0
    def buildTree(self, nt, item, tokens, k):
        state, parent = item

        choices = []
        for rule in self.states[state].complete:
            if rule[0] == nt:
                choices.append(rule)
        rule = choices[0]
        if len(choices) > 1:
            rule = self.ambiguity(choices)

        rhs = rule[1]
        attr = [None] * len(rhs)

        for i in range(len(rhs)-1, -1, -1):
            sym = rhs[i]
            if sym not in self.newrules:
                if sym != self._BOF:
                    attr[i] = tokens[k-1]
                    key = (item, k)
                    item, k = self.predecessor(key, None)
            elif self._NULLABLE == sym[0:len(self._NULLABLE)]:
                attr[i] = self.deriveEpsilon(sym)
            else:
                key = (item, k)
                why = self.causal(key)
                attr[i] = self.buildTree(sym, why[0],
                                         tokens, why[1])
                item, k = self.predecessor(key, why)
        return self.rule2func[self.new2old[rule]](attr)
Exemplo n.º 4
0
 def parse(self, tokens):
     sets = [[(1, 0), (2, 0)]]
     self.links = {}
     if self.ruleschanged:
         self.computeNull()
         self.newrules = {}
         self.new2old = {}
         self.makeNewRules()
         self.ruleschanged = 0
         self.edges, self.cores = {}, {}
         self.states = {0: self.makeState0()}
         self.makeState(0, self._BOF)
     for i in range(len(tokens)):
         sets.append([])
         if sets[i] == []:
             break
         self.makeSet(tokens[i], sets, i)
     else:
         sets.append([])
         self.makeSet(None, sets, len(tokens))
     finalitem = (self.finalState(tokens), 0)
     if finalitem not in sets[-2]:
         if len(tokens) > 0:
             self.error(tokens[i-1])
         else:
             self.error(None)
     return self.buildTree(self._START, finalitem,
                           tokens, len(sets)-2)
Exemplo n.º 5
0
 def test_operators(self):
     from xoutil.eight import range
     from xoutil.collections import BitPascalSet
     g = lambda s: (i for i in s)
     s1 = BitPascalSet[1:4, 9, 15:18]
     r1 = range(1, 18)
     s2 = BitPascalSet(s1, 20)
     self.assertTrue(s1.issubset(s1))
     self.assertTrue(s1.issubset(set(s1)))
     self.assertTrue(s1.issubset(list(s1)))
     self.assertTrue(s1.issubset(g(s1)))
     self.assertTrue(s1.issubset(r1))
     self.assertTrue(s1.issubset(set(r1)))
     self.assertTrue(s1.issubset(list(r1)))
     self.assertTrue(s1.issubset(g(r1)))
     self.assertTrue(s2.issuperset(s2))
     self.assertTrue(s2.issuperset(s1))
     self.assertTrue(s2.issuperset(set(s1)))
     self.assertTrue(s2.issuperset(list(s1)))
     self.assertTrue(s2.issuperset(g(s1)))
     self.assertTrue(s1 <= set(s1))
     self.assertTrue(s1 < s2)
     self.assertTrue(s1 <= s2)
     self.assertTrue(s1 < set(s2))
     self.assertTrue(s1 <= set(s2))
     self.assertTrue(s1 < set(r1))
     self.assertTrue(s1 <= set(r1))
     self.assertTrue(s2 >= s2)
     self.assertTrue(s2 >= set(s2))
     self.assertTrue(s2 > s1)
     self.assertTrue(s2 > set(s1))
     self.assertTrue(s2 >= s1)
     self.assertTrue(s2 >= set(s1))
Exemplo n.º 6
0
 def test_syntax_sugar(self):
     from xoutil.eight import range
     from xoutil.collections import BitPascalSet
     s1 = BitPascalSet[1:4, 9, 15:18]
     s2 = BitPascalSet[3:18]
     self.assertEqual(str(s1), '{1..3, 9, 15..17}')
     self.assertEqual(str(s1 ^ s2), '{1, 2, 4..8, 10..14}')
     self.assertEqual(list(BitPascalSet[3:18]), list(range(3, 18)))
Exemplo n.º 7
0
def test_iscollection():
    from xoutil.eight import range
    from xoutil.types import is_collection
    from xoutil.collections import UserList, UserDict
    assert is_collection('all strings are iterable') is False
    assert is_collection(1) is False
    assert is_collection(range(1)) is True
    assert is_collection({}) is False
    assert is_collection(tuple()) is True
    assert is_collection(set()) is True
    assert is_collection(a for a in range(100)) is True

    class Foobar(UserList):
        pass

    assert is_collection(Foobar()) is True

    class Foobar(UserDict):
        pass

    assert is_collection(Foobar()) is False
Exemplo n.º 8
0
    def test_pickle(self):
        ns = types.SimpleNamespace(breakfast="spam", lunch="spam")

        for protocol in range(pickle.HIGHEST_PROTOCOL + 1):
            pname = "protocol {}".format(protocol)
            try:
                ns_pickled = pickle.dumps(ns, protocol)
            except TypeError:
                raise TypeError(pname)
            ns_roundtrip = pickle.loads(ns_pickled)

            self.assertEqual(ns, ns_roundtrip, pname)
Exemplo n.º 9
0
    def deriveEpsilon(self, nt):
        if len(self.newrules[nt]) > 1:
            rule = self.ambiguity(self.newrules[nt])
        else:
            rule = self.newrules[nt][0]

        rhs = rule[1]
        attr = [None] * len(rhs)

        for i in range(len(rhs)-1, -1, -1):
            attr[i] = self.deriveEpsilon(rhs[i])
        return self.rule2func[self.new2old[rule]](attr)
Exemplo n.º 10
0
    def test_multiset_operations(self):
        # Verify that adding a zero counter will strip zeros and negatives
        c = Counter(a=10, b=-2, c=0) + Counter()
        self.assertEqual(dict(c), dict(a=10))

        elements = 'abcd'
        for i in range(1000):
            # test random pairs of multisets
            p = Counter(dict((elem, randrange(-2, 4)) for elem in elements))
            p.update(e=1, f=-1, g=0)
            q = Counter(dict((elem, randrange(-2, 4)) for elem in elements))
            q.update(h=1, i=-1, j=0)
            for counterop, numberop in [
                (Counter.__add__, lambda x, y: max(0, x+y)),
                (Counter.__sub__, lambda x, y: max(0, x-y)),
                (Counter.__or__, lambda x, y: max(0, x, y)),
                (Counter.__and__, lambda x, y: max(0, min(x, y))),
            ]:
                result = counterop(p, q)
                for x in elements:
                    self.assertEqual(numberop(p[x], q[x]), result[x],
                                     (counterop, x, p, q))
                # verify that results exclude non-positive counts
                self.assertTrue(x > 0 for x in result.values())

        elements = 'abcdef'
        for i in range(100):
            # verify that random multisets with no repeats are exactly like
            # sets
            p = Counter(dict((elem, randrange(0, 2)) for elem in elements))
            q = Counter(dict((elem, randrange(0, 2)) for elem in elements))
            for counterop, setop in [
                (Counter.__sub__, set.__sub__),
                (Counter.__or__, set.__or__),
                (Counter.__and__, set.__and__),
            ]:
                counter_result = counterop(p, q)
                set_result = setop(set(p.elements()), set(q.elements()))
                self.assertEqual(counter_result, dict.fromkeys(set_result, 1))
Exemplo n.º 11
0
 def _normalize_positions(self):
     '''Update the `positions` dictionaries.'''
     from xoutil.eight import range, iteritems
     aux = {}
     for par, ps in iteritems(self.scheme):
         for pos in ps['pos']:
             l = aux.setdefault(pos, [])
             l.append(par)
     res, pivot = {}, 0
     for pos in range(min(aux), max(aux) + 1):
         if pos in aux:
             res[pivot] = sorted(aux[pos])
             pivot += 1
     self.positions = res
Exemplo n.º 12
0
    def ambiguity(self, rules):
        #
        #  XXX - problem here and in collectRules() if the same rule
        #        appears in >1 method.  Also undefined results if rules
        #        causing the ambiguity appear in the same method.
        #

        sortlist = []
        name2index = {}
        for i in range(len(rules)):
            lhs, rhs = rule = rules[i]
            name = self.rule2name[self.new2old[rule]]
            sortlist.append((len(rhs), name))
            name2index[name] = i
        sortlist.sort()
        list = [a_b[1] for a_b in sortlist]
        return rules[name2index[self.resolve(list)]]
Exemplo n.º 13
0
 def test_inplace_operations(self):
     elements = 'abcd'
     for i in range(1000):
         # test random pairs of multisets
         p = Counter(dict((elem, randrange(-2, 4)) for elem in elements))
         p.update(e=1, f=-1, g=0)
         q = Counter(dict((elem, randrange(-2, 4)) for elem in elements))
         q.update(h=1, i=-1, j=0)
         for inplace_op, regular_op in [
             (Counter.__iadd__, Counter.__add__),
             (Counter.__isub__, Counter.__sub__),
             (Counter.__ior__, Counter.__or__),
             (Counter.__iand__, Counter.__and__),
         ]:
             c = p.copy()
             c_id = id(c)
             regular_result = regular_op(c, q)
             inplace_result = inplace_op(c, q)
             self.assertEqual(inplace_result, regular_result)
             self.assertEqual(id(inplace_result), c_id)
Exemplo n.º 14
0
 def test_basics(self):
     c = Counter('abcaba')
     self.assertEqual(c, Counter({'a': 3, 'b': 2, 'c': 1}))
     self.assertEqual(c, Counter(a=3, b=2, c=1))
     self.assert_(isinstance(c, dict))
     self.assert_(isinstance(c, Mapping))
     self.assertTrue(issubclass(Counter, dict))
     self.assertTrue(issubclass(Counter, Mapping))
     self.assertEqual(len(c), 3)
     self.assertEqual(sum(c.values()), 6)
     self.assertEqual(sorted(c.values()), [1, 2, 3])
     self.assertEqual(sorted(c.keys()), ['a', 'b', 'c'])
     self.assertEqual(sorted(c), ['a', 'b', 'c'])
     self.assertEqual(sorted(c.items()),
                      [('a', 3), ('b', 2), ('c', 1)])
     self.assertEqual(c['b'], 2)
     self.assertEqual(c['z'], 0)
     self.assertEqual(c.__contains__('c'), True)
     self.assertEqual(c.__contains__('z'), False)
     self.assertEqual(c.get('b', 10), 2)
     self.assertEqual(c.get('z', 10), 10)
     self.assertEqual(c, dict(a=3, b=2, c=1))
     if not PY3:
         self.assertEqual(repr(c), "Counter({u'a': 3, u'b': 2, u'c': 1})")
     else:
         self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})")
     self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)])
     for i in range(5):
         self.assertEqual(c.most_common(i),
                          [('a', 3), ('b', 2), ('c', 1)][:i])
     self.assertEqual(''.join(sorted(c.elements())), 'aaabbc')
     c['a'] += 1         # increment an existing value
     c['b'] -= 2         # sub existing value to zero
     del c['c']          # remove an entry
     del c['c']          # make sure that del doesn't raise KeyError
     c['d'] -= 2         # sub from a missing value
     c['e'] = -5         # directly assign a missing value
     c['f'] += 4         # add to a missing value
     self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4))
     self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff')
     self.assertEqual(c.pop('f'), 4)
     self.assertNotIn('f', c)
     for i in range(3):
         elem, cnt = c.popitem()
         self.assertNotIn(elem, c)
     c.clear()
     self.assertEqual(c, {})
     self.assertEqual(repr(c), 'Counter()')
     self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc')
     self.assertRaises(TypeError, hash, c)
     c.update(dict(a=5, b=3))
     c.update(c=1)
     c.update(Counter('a' * 50 + 'b' * 30))
     c.update()          # test case with no args
     c.__init__('a' * 500 + 'b' * 300)
     c.__init__('cdc')
     c.__init__()
     self.assertEqual(c, dict(a=555, b=333, c=3, d=1))
     self.assertEqual(c.setdefault('d', 5), 1)
     self.assertEqual(c['d'], 1)
     self.assertEqual(c.setdefault('e', 5), 5)
     self.assertEqual(c['e'], 5)
Exemplo n.º 15
0
def nameof(*args, **kwargs):
    '''Obtain the name of each one of a set of objects.

    .. versionadded:: 1.4.0

    .. versionchanged:: 1.6.0

       - Keyword arguments are now keyword-only arguments.

       - Support for several objects

       - Improved the semantics of parameter `full`.

       - Added the `safe` keyword argument.

    If no object is given, None is returned; if only one object is given, a
    single string is returned; otherwise a list of strings is returned.

    The name of an object is normally the variable name in the calling stack.

    If the object is not present calling frame, up to five frame levels are
    searched.  Use the `depth` keyword argument to specify a different
    starting point and the search will proceed five levels from this frame up.

    If the same object has several good names a single one is arbitrarily
    chosen.

    Good names candidates are retrieved based on the keywords arguments
    `full`, `inner`, `safe` and `typed`.

    If `typed` is True and the object is not a type name or a callable (see
    `xoutil.inspect.type_name`:func:), then the `type` of the object is used
    instead.

    If `inner` is True we try to extract the name by introspection instead of
    looking for the object in the frame stack::

    If `full` is True the full identifier of the object is preferred.  In this
    case if `inner` is False the local-name for the object is found.  If
    `inner` is True, find the import-name.

    If `safe` is True, returned value is converted -if it is not- into a valid
    Python identifier, though you should not trust this identifier resolves to
    the value.

    See `the examples in the documentation <name-of-narrative>`:ref:.

    '''
    # XXX: The examples are stripped from here.  Go the documentation page.
    from numbers import Number
    from xoutil.eight import range
    from xoutil.inspect import type_name
    arg_count = len(args)
    names = [[] for i in range(arg_count)]

    class vars:
        '`nonlocal` simulation'
        params = kwargs
        idx = 0

    def grant(name=None, **again):
        if name:
            names[vars.idx].append(name)
            assert len(names[vars.idx]) < 5
        if again:
            vars.params = dict(kwargs, **again)
        else:
            vars.params = kwargs
            vars.idx += 1

    def param(name, default=False):
        return vars.params.get(name, default)

    while vars.idx < arg_count:
        item = args[vars.idx]
        if param('typed') and not type_name(item):
            item = type(item)
        if param('inner'):
            res = type_name(item)
            if res:
                if param('full'):
                    head = module_name(item)
                    if head:
                        res = '.'.join((head, res))
                grant(res)
            elif isinstance(item, (base_string, Number)):
                grant(str(item))
            else:
                grant('@'.join(('%(next)s', hex(id(item)))), typed=True)
        else:
            import sys
            sf = sys._getframe(param('depth', 1))
            try:
                i, LIMIT, res = 0, 5, _undef
                _full = param('full')
                while not res and sf and (i < LIMIT):
                    key, mapping = _key_for_value(sf, item)
                    if key and _full:
                        head = module_name(_get_value(mapping, '__name__'))
                        if not head:
                            head = module_name(sf.f_code.co_name)
                        if not head:
                            head = module_name(item) or None
                    else:
                        head = None
                    if key:
                        res = key
                    else:
                        sf = sf.f_back
                        i += 1
            finally:
                # TODO: on "del sf" Python says "SyntaxError: can not delete
                # variable 'sf' referenced in nested scope".
                sf = None
            if res:
                grant('.'.join((head, res)) if head else res)
            else:
                res = type_name(item)
                if res:
                    grant(res)
                else:
                    grant(None, inner=True)
    for i in range(arg_count):
        names[i] = _get_best_name(names[i], safe=param('safe'))
    if arg_count == 0:
        return None
    elif arg_count == 1:
        return names[0]
    else:
        return names