├── requirements.txt ├── setup.cfg ├── tests ├── __init__.py └── collections │ ├── __init__.py │ └── test_collection.py ├── tests-requirements.txt ├── backpack ├── version.py ├── __init__.py ├── collections │ ├── __init__.py │ ├── collection.py │ ├── _collection.pyx │ └── base_collection.py └── _utils │ ├── __init__.py │ ├── _helpers.pyx │ ├── helpers.py │ └── _helpers.c ├── MANIFEST.in ├── .travis.yml ├── .gitignore ├── tox.ini ├── Makefile ├── LICENSE ├── setup.py └── README.rst /requirements.txt: -------------------------------------------------------------------------------- 1 | simplejson 2 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal = 1 3 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /tests-requirements.txt: -------------------------------------------------------------------------------- 1 | -r requirements.txt 2 | pytest 3 | -------------------------------------------------------------------------------- /tests/collections/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | -------------------------------------------------------------------------------- /backpack/version.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | VERSION = '0.1' 4 | -------------------------------------------------------------------------------- /backpack/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from .collections import collect, Collection 4 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst LICENSE requirements.txt test-requirements.txt 2 | recursive-exclude tests * 3 | recursive-exclude benchmark * 4 | -------------------------------------------------------------------------------- /backpack/collections/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from .collection import Collection 4 | 5 | 6 | def collect(items): 7 | return Collection(items) 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | python: 4 | - "2.7" 5 | - "3.5" 6 | 7 | env: 8 | - BACKPACK_EXTENSIONS=true 9 | - BACKPACK_EXTENSIONS=false 10 | 11 | install: 12 | - pip install -r tests-requirements.txt 13 | 14 | script: py.test tests/ 15 | -------------------------------------------------------------------------------- /backpack/collections/collection.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from .base_collection import BaseCollection 4 | 5 | try: 6 | from ._collection import Collection as ExtCollection 7 | except ImportError: 8 | class ExtCollection: 9 | pass 10 | 11 | 12 | class Collection(ExtCollection, BaseCollection): 13 | 14 | pass 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | 3 | # Packages 4 | *.egg 5 | *.egg-info 6 | dist 7 | build 8 | _build 9 | .cache 10 | *.so 11 | 12 | # Installer logs 13 | pip-log.txt 14 | 15 | # Unit test / coverage reports 16 | .coverage 17 | .tox 18 | nosetests.xml 19 | 20 | .DS_Store 21 | .idea/* 22 | 23 | /test.py 24 | /test_*.py 25 | /benchmark/* 26 | benchmark.py 27 | results.json 28 | profile.html 29 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = py{27,35}-{without,with}-extensions,pypy 3 | 4 | [testenv] 5 | deps = -rrequirements.txt 6 | -rtests-requirements.txt 7 | commands = py.test tests -sq 8 | setenv = 9 | without-extensions: BACKPACK_EXTENSIONS=false 10 | with-extensions: BACKPACK_EXTENSIONS=true 11 | 12 | [testenv:flake8] 13 | basepython=python 14 | deps=flake8 15 | commands= 16 | flake8 cleo 17 | -------------------------------------------------------------------------------- /backpack/_utils/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import sys 4 | import warnings 5 | import functools 6 | 7 | PY2 = sys.version_info[0] == 2 8 | PY3K = sys.version_info[0] >= 3 9 | PY33 = sys.version_info >= (3, 3) 10 | 11 | if PY2: 12 | import imp 13 | 14 | long = long 15 | unicode = unicode 16 | basestring = basestring 17 | 18 | reduce = reduce 19 | else: 20 | long = int 21 | unicode = str 22 | basestring = str 23 | 24 | from functools import reduce 25 | 26 | 27 | from .helpers import value, data_get, mkdir_p 28 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # This file is part of orator 2 | # https://github.com/sdispater/orator 3 | 4 | # Licensed under the MIT license: 5 | # http://www.opensource.org/licenses/MIT-license 6 | # Copyright (c) 2015 Sébastien Eustace 7 | 8 | # lists all available targets 9 | list: 10 | @sh -c "$(MAKE) -p no_targets__ | \ 11 | awk -F':' '/^[a-zA-Z0-9][^\$$#\/\\t=]*:([^=]|$$)/ {\ 12 | split(\$$1,A,/ /);for(i in A)print A[i]\ 13 | }' | grep -v '__\$$' | grep -v 'make\[1\]' | grep -v 'Makefile' | sort" 14 | # required for list 15 | no_targets__: 16 | 17 | # install all dependencies 18 | setup: setup-python 19 | 20 | # test your application (tests in the tests/ directory) 21 | test: 22 | @py.test --cov=pendulum --cov-config .coveragerc tests/ -sq 23 | 24 | # run tests against all supported python versions 25 | tox: 26 | @tox 27 | 28 | extensions: 29 | @echo 'Making C extensions' 30 | cython backpack/collections/_collection.pyx 31 | cython backpack/_utils/_helpers.pyx 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Sébastien Eustace 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /backpack/_utils/_helpers.pyx: -------------------------------------------------------------------------------- 1 | def value(val): 2 | if callable(val): 3 | return val() 4 | 5 | return val 6 | 7 | 8 | def data_get(target, key, default=None): 9 | """ 10 | Get an item from a list, a dict or an object using "dot" notation. 11 | 12 | :param target: The target element 13 | :type target: list or dict or object 14 | 15 | :param key: The key to get 16 | :type key: string or list 17 | 18 | :param default: The default value 19 | :type default: mixed 20 | 21 | :rtype: mixed 22 | """ 23 | return _data_get(target, key, default) 24 | 25 | 26 | cdef _data_get(target, key, default=None): 27 | if key is None: 28 | return target 29 | 30 | if not isinstance(key, list): 31 | key = key.split('.') 32 | 33 | for segment in key: 34 | if isinstance(target, (list, tuple)): 35 | try: 36 | target = target[segment] 37 | except IndexError: 38 | return value(default) 39 | elif isinstance(target, dict): 40 | try: 41 | target = target[segment] 42 | except IndexError: 43 | return value(default) 44 | else: 45 | try: 46 | target = target[segment] 47 | except (IndexError, KeyError, TypeError): 48 | try: 49 | target = getattr(target, segment) 50 | except AttributeError: 51 | return value(default) 52 | 53 | return target 54 | -------------------------------------------------------------------------------- /backpack/_utils/helpers.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | import errno 5 | 6 | 7 | try: 8 | from ._helpers import value, data_get 9 | _c_ext = True 10 | except ImportError: 11 | _c_ext = False 12 | 13 | if not _c_ext: 14 | def value(val): 15 | if callable(val): 16 | return val() 17 | 18 | return val 19 | 20 | 21 | def data_get(target, key, default=None): 22 | """ 23 | Get an item from a list, a dict or an object using "dot" notation. 24 | 25 | :param target: The target element 26 | :type target: list or dict or object 27 | 28 | :param key: The key to get 29 | :type key: string or list 30 | 31 | :param default: The default value 32 | :type default: mixed 33 | 34 | :rtype: mixed 35 | """ 36 | if key is None: 37 | return target 38 | 39 | if not isinstance(key, list): 40 | key = key.split('.') 41 | 42 | for segment in key: 43 | if isinstance(target, (list, tuple)): 44 | try: 45 | target = target[segment] 46 | except IndexError: 47 | return value(default) 48 | elif isinstance(target, dict): 49 | try: 50 | target = target[segment] 51 | except IndexError: 52 | return value(default) 53 | else: 54 | try: 55 | target = target[segment] 56 | except (IndexError, KeyError, TypeError): 57 | try: 58 | target = getattr(target, segment) 59 | except AttributeError: 60 | return value(default) 61 | 62 | return target 63 | 64 | 65 | def mkdir_p(path, mode=0o777): 66 | try: 67 | os.makedirs(path, mode) 68 | except OSError as exc: 69 | if exc.errno == errno.EEXIST and os.path.isdir(path): 70 | pass 71 | else: 72 | raise 73 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os 4 | import sys 5 | from setuptools import find_packages 6 | from distutils.command.build_ext import build_ext 7 | from distutils.core import setup 8 | from distutils.extension import Extension 9 | from distutils.version import StrictVersion 10 | from distutils.errors import (CCompilerError, DistutilsExecError, 11 | DistutilsPlatformError) 12 | 13 | 14 | here = os.path.abspath(os.path.dirname(__file__)) 15 | 16 | def get_version(): 17 | with open(os.path.join(here, 'backpack/version.py')) as f: 18 | variables = {} 19 | exec(f.read(), variables) 20 | 21 | version = variables.get('VERSION') 22 | if version: 23 | return version 24 | 25 | raise RuntimeError('No version info found.') 26 | 27 | 28 | __version__ = get_version() 29 | 30 | with open('%s/requirements.txt' % here) as f: 31 | requirements = f.readlines() 32 | 33 | 34 | # Optional C extensions 35 | 36 | if sys.platform == 'win32': 37 | build_ext_errors = (CCompilerError, DistutilsExecError, 38 | DistutilsPlatformError, IOError) 39 | else: 40 | build_ext_errors = (CCompilerError, DistutilsExecError, 41 | DistutilsPlatformError) 42 | 43 | class BuildExtFailed(Exception): 44 | pass 45 | 46 | with_extensions = os.environ.get('BACKPACK_EXTENSIONS', None) 47 | 48 | if with_extensions: 49 | if with_extensions.lower() == 'true': 50 | with_extensions = True 51 | elif with_extensions.lower() == 'false': 52 | with_extensions = False 53 | else: 54 | with_extensions = None 55 | 56 | if hasattr(sys, 'pypy_version_info'): 57 | with_extensions = False 58 | 59 | extensions = ( 60 | ('backpack.collections._collection', ('backpack/collections/_collection.pyx', 61 | 'backpack/collections/_collection.c')), 62 | ('backpack._utils._helpers', ('backpack/_utils/_helpers.pyx', 63 | 'backpack/_utils/_helpers.c')), 64 | ) 65 | 66 | ext_modules = None 67 | if with_extensions is True or with_extensions is None: 68 | cython_min = '0.22.1' 69 | try: 70 | from Cython.Distutils import build_ext 71 | from Cython import __version__ as cython_ver 72 | except ImportError: 73 | cython_installed = False 74 | else: 75 | cython_installed = StrictVersion(cython_ver) >= StrictVersion(cython_min) 76 | 77 | ext_modules = [Extension(module, [pyx if cython_installed else c], extra_compile_args=['-Wno-unused-function']) 78 | for module, (pyx, c) in extensions] 79 | 80 | 81 | class optional_build_ext(build_ext): 82 | def run(self): 83 | try: 84 | build_ext.run(self) 85 | except DistutilsPlatformError: 86 | raise BuildExtFailed() 87 | 88 | def build_extension(self, ext): 89 | try: 90 | build_ext.build_extension(self, ext) 91 | except build_ext_errors: 92 | raise BuildExtFailed() 93 | 94 | 95 | 96 | setup_kwargs = dict( 97 | name='backpack', 98 | license='MIT', 99 | version=__version__, 100 | description='Useful utilities for Python.', 101 | long_description=open('README.rst').read(), 102 | author='Sébastien Eustace', 103 | author_email='sebastien@eustace.io', 104 | url='https://github.com/sdispater/backpack', 105 | download_url='https://github.com/sdispater/backpack/archive/%s.tar.gz' % __version__, 106 | packages=find_packages(exclude=['tests']), 107 | install_requires=requirements, 108 | tests_require=['pytest'], 109 | test_suite='nose.collector', 110 | classifiers=[ 111 | 'Intended Audience :: Developers', 112 | 'Operating System :: OS Independent', 113 | 'Programming Language :: Python', 114 | 'Topic :: Software Development :: Libraries :: Python Modules', 115 | ], 116 | ) 117 | 118 | def run_setup(ext_modules=None): 119 | setup_kwargs_tmp = dict(setup_kwargs) 120 | 121 | if ext_modules: 122 | setup_kwargs_tmp['ext_modules'] = ext_modules 123 | setup_kwargs_tmp['cmdclass'] = {'build_ext': optional_build_ext} 124 | 125 | setup(**setup_kwargs_tmp) 126 | 127 | 128 | try: 129 | run_setup(ext_modules) 130 | except BuildExtFailed: 131 | run_setup() 132 | -------------------------------------------------------------------------------- /backpack/collections/_collection.pyx: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from backpack._utils._helpers import data_get 4 | 5 | 6 | cdef class Collection(object): 7 | 8 | cdef list _items 9 | 10 | def __init__(self, items=None): 11 | """ 12 | Creates a new Collection 13 | 14 | :param items: The collection items 15 | :type items: dict or list or Collection or map 16 | 17 | :rtype: None 18 | """ 19 | cdef list _items 20 | 21 | if items is None: 22 | _items = [] 23 | else: 24 | _items = self._get_items(items) 25 | 26 | self._items = _items 27 | 28 | @property 29 | def items(self): 30 | return self._items\ 31 | 32 | @classmethod 33 | def make(cls, items=None): 34 | """ 35 | Create a new Collection instance if the value isn't one already 36 | 37 | :param items: The collection items 38 | :type items: dict or list or Collection 39 | 40 | :return: A Collection instance 41 | :rtype: Collection 42 | """ 43 | if isinstance(items, cls): 44 | return items 45 | 46 | return cls(items) 47 | 48 | def avg(self, key=None): 49 | """ 50 | Get the average value of a given key. 51 | 52 | :param key: The key to get the average for 53 | :type key: mixed 54 | 55 | :rtype: float 56 | """ 57 | cdef int count 58 | 59 | count = self.count() 60 | 61 | if count: 62 | return self.sum(key) / count 63 | 64 | def count(self): 65 | return len(self._items) 66 | 67 | def _chunk(self, size): 68 | """ 69 | Chunk the underlying collection. 70 | 71 | :param size: The chunk size 72 | :type size: int 73 | 74 | :rtype: Collection 75 | """ 76 | cdef list items 77 | 78 | items = self._items 79 | 80 | return [items[i:i + size] for i in range(0, len(items), size)] 81 | 82 | def merge(self, items): 83 | """ 84 | Merge the collection with the given items. 85 | 86 | :param items: The items to merge 87 | :type items: list or Collection 88 | 89 | :rtype: Collection 90 | """ 91 | cdef list _items 92 | 93 | if isinstance(items, Collection): 94 | _items = items.all() 95 | else: 96 | _items = items 97 | 98 | if not isinstance(_items, list): 99 | raise ValueError('Unable to merge uncompatible types') 100 | 101 | self._items += _items 102 | 103 | return self 104 | 105 | def sum(self, callback=None): 106 | """ 107 | Get the sum of the given values. 108 | 109 | :param callback: The callback 110 | :type callback: callable or string or None 111 | 112 | :rtype: mixed 113 | """ 114 | if callback is None: 115 | return sum(self.items) 116 | 117 | callback = self._value_retriever(callback) 118 | 119 | return self.reduce(lambda result, item: (result or 0) + callback(item)) 120 | 121 | def transform(self, callback): 122 | """ 123 | Transform each item in the collection using a callback. 124 | 125 | :param callback: The callback 126 | :type callback: callable 127 | 128 | :rtype: Collection 129 | """ 130 | self._items = self.map(callback).all() 131 | 132 | return self 133 | 134 | def unique(self, key=None): 135 | """ 136 | Return only unique items from the collection list. 137 | 138 | :param key: The key to chech uniqueness on 139 | :type key: mixed 140 | 141 | :rtype: Collection 142 | """ 143 | cdef set seen 144 | cdef list exists 145 | 146 | if key is None: 147 | seen = set() 148 | seen_add = seen.add 149 | 150 | return self.__class__([x for x in self.items if not (x in seen or seen_add(x))]) 151 | 152 | key = self._value_retriever(key) 153 | 154 | exists = [] 155 | 156 | def _check(item): 157 | id_ = key(item) 158 | if id_ in exists: 159 | return True 160 | 161 | exists.append(id_) 162 | 163 | return self.reject(_check) 164 | 165 | def _value_retriever(self, value): 166 | """ 167 | Get a value retrieving callback. 168 | 169 | :type value: mixed 170 | 171 | :rtype: callable 172 | """ 173 | if self._use_as_callable(value): 174 | return value 175 | 176 | return lambda item: data_get(item, value) 177 | 178 | def _set_items(self, items): 179 | self._items = items 180 | 181 | cdef list _get_items(self, items): 182 | if isinstance(items, list): 183 | return items 184 | elif isinstance(items, tuple): 185 | return list(items) 186 | elif isinstance(items, Collection): 187 | return items.all() 188 | elif hasattr('items', 'to_list'): 189 | return items.to_list() 190 | 191 | return [items] 192 | -------------------------------------------------------------------------------- /tests/collections/test_collection.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from unittest import TestCase 4 | from backpack import Collection 5 | 6 | 7 | class CollectionTestCase(TestCase): 8 | 9 | def test_first_returns_first_item_in_collection(self): 10 | c = Collection(['foo', 'bar']) 11 | 12 | self.assertEqual('foo', c.first()) 13 | 14 | def test_last_returns_last_item_in_collection(self): 15 | c = Collection(['foo', 'bar']) 16 | 17 | self.assertEqual('bar', c.last()) 18 | 19 | def test_pop_removes_and_returns_last_item_or_specified_index(self): 20 | c = Collection(['foo', 'bar']) 21 | 22 | self.assertEqual('bar', c.pop()) 23 | self.assertEqual('foo', c.last()) 24 | 25 | c = Collection(['foo', 'bar']) 26 | 27 | self.assertEqual('foo', c.pop(0)) 28 | self.assertEqual('bar', c.first()) 29 | 30 | def test_shift_removes_and_returns_first_item(self): 31 | c = Collection(['foo', 'bar']) 32 | 33 | self.assertEqual('foo', c.shift()) 34 | self.assertEqual('bar', c.first()) 35 | 36 | def test_empty_collection_is_empty(self): 37 | c = Collection() 38 | c2 = Collection([]) 39 | 40 | self.assertTrue(c.is_empty()) 41 | self.assertTrue(c2.is_empty()) 42 | 43 | def test_collection_is_constructed(self): 44 | c = Collection('foo') 45 | self.assertEqual(['foo'], c.all()) 46 | 47 | c = Collection(2) 48 | self.assertEqual([2], c.all()) 49 | 50 | c = Collection(False) 51 | self.assertEqual([False], c.all()) 52 | 53 | c = Collection(None) 54 | self.assertEqual([], c.all()) 55 | 56 | c = Collection() 57 | self.assertEqual([], c.all()) 58 | 59 | def test_offset_access(self): 60 | c = Collection(['foo', 'bar']) 61 | self.assertEqual('bar', c[1]) 62 | 63 | c[1] = 'baz' 64 | self.assertEqual('baz', c[1]) 65 | 66 | del c[0] 67 | self.assertEqual('baz', c[0]) 68 | 69 | def test_forget(self): 70 | c = Collection(['foo', 'bar', 'boom']) 71 | c.forget(0) 72 | self.assertEqual('bar', c[0]) 73 | c.forget(0, 1) 74 | self.assertTrue(c.is_empty()) 75 | 76 | def test_get_avg_items_from_collection(self): 77 | c = Collection([{'foo': 10}, {'foo': 20}]) 78 | self.assertEqual(15, c.avg('foo')) 79 | 80 | c = Collection([1, 2, 3, 4, 5]) 81 | self.assertEqual(3, c.avg()) 82 | 83 | c = Collection() 84 | self.assertIsNone(c.avg()) 85 | 86 | def test_collapse(self): 87 | obj1 = object() 88 | obj2 = object() 89 | 90 | c = Collection([[obj1], [obj2]]) 91 | self.assertEqual([obj1, obj2], c.collapse().all()) 92 | 93 | def test_collapse_with_nested_collection(self): 94 | c = Collection([Collection([1, 2, 3]), Collection([4, 5, 6])]) 95 | self.assertEqual([1, 2, 3, 4, 5, 6], c.collapse().all()) 96 | 97 | def test_contains(self): 98 | c = Collection([1, 3, 5]) 99 | 100 | self.assertTrue(c.contains(1)) 101 | self.assertFalse(c.contains(2)) 102 | self.assertTrue(c.contains(lambda x: x < 5)) 103 | self.assertFalse(c.contains(lambda x: x > 5)) 104 | self.assertIn(3, c) 105 | 106 | c = Collection([{'v': 1}, {'v': 3}, {'v': 5}]) 107 | self.assertTrue(c.contains('v', 1)) 108 | self.assertFalse(c.contains('v', 2)) 109 | 110 | obj1 = type('lamdbaobject', (object,), {})() 111 | obj1.v = 1 112 | obj2 = type('lamdbaobject', (object,), {})() 113 | obj2.v = 3 114 | obj3 = type('lamdbaobject', (object,), {})() 115 | obj3.v = 5 116 | c = Collection([{'v': 1}, {'v': 3}, {'v': 5}]) 117 | self.assertTrue(c.contains('v', 1)) 118 | self.assertFalse(c.contains('v', 2)) 119 | 120 | def test_countable(self): 121 | c = Collection(['foo', 'bar']) 122 | self.assertEqual(2, c.count()) 123 | self.assertEqual(2, len(c)) 124 | 125 | def test_diff(self): 126 | c = Collection(['foo', 'bar']) 127 | self.assertEqual(['foo'], c.diff(Collection(['bar', 'baz'])).all()) 128 | 129 | def test_each(self): 130 | original = ['foo', 'bar', 'baz'] 131 | c = Collection(original) 132 | 133 | result = [] 134 | c.each(lambda x: result.append(x)) 135 | self.assertEqual(result, original) 136 | self.assertEqual(original, c.all()) 137 | 138 | def test_every(self): 139 | c = Collection([1, 2, 3, 4, 5, 6]) 140 | self.assertEqual([1, 3, 5], c.every(2).all()) 141 | self.assertEqual([2, 4, 6], c.every(2, 1).all()) 142 | 143 | def test_filter(self): 144 | c = Collection([{'id': 1, 'name': 'hello'}, {'id': 2, 'name': 'world'}]) 145 | self.assertEqual([{'id': 2, 'name': 'world'}], c.filter(lambda item: item['id'] == 2).all()) 146 | 147 | c = Collection(['', 'hello', '', 'world']) 148 | self.assertEqual(['hello', 'world'], c.filter().all()) 149 | 150 | def test_where(self): 151 | c = Collection([{'v': 1}, {'v': 3}, {'v': 2}, {'v': 3}, {'v': 4}]) 152 | self.assertEqual([{'v': 3}, {'v': 3}], c.where('v', 3).all()) 153 | 154 | def test_implode(self): 155 | obj1 = type('lamdbaobject', (object,), {})() 156 | obj1.name = 'john' 157 | obj1.email = 'foo' 158 | c = Collection([{'name': 'john', 'email': 'foo'}, {'name': 'jane', 'email': 'bar'}]) 159 | self.assertEqual('foobar', c.implode('email')) 160 | self.assertEqual('foo,bar', c.implode('email', ',')) 161 | 162 | c = Collection(['foo', 'bar']) 163 | self.assertEqual('foobar', c.implode('')) 164 | self.assertEqual('foo,bar', c.implode(',')) 165 | 166 | def test_lists(self): 167 | obj1 = type('lamdbaobject', (object,), {})() 168 | obj1.name = 'john' 169 | obj1.email = 'foo' 170 | c = Collection([obj1, {'name': 'jane', 'email': 'bar'}]) 171 | self.assertEqual({'john': 'foo', 'jane': 'bar'}, c.lists('email', 'name')) 172 | self.assertEqual(['foo', 'bar'], c.pluck('email').all()) 173 | 174 | def test_map(self): 175 | c = Collection([1, 2, 3, 4, 5]) 176 | self.assertEqual([3, 4, 5, 6, 7], c.map(lambda x: x + 2).all()) 177 | 178 | def test_merge(self): 179 | c = Collection([1, 2, 3]) 180 | c.merge([4, 5, 6]) 181 | self.assertEqual([1, 2, 3, 4, 5, 6], c.all()) 182 | 183 | c = Collection(Collection([1, 2, 3])) 184 | c.merge([4, 5, 6]) 185 | self.assertEqual([1, 2, 3, 4, 5, 6], c.all()) 186 | 187 | def test_for_page(self): 188 | c = Collection([1, 2, 3, 4, 5, 6]) 189 | self.assertEqual([4, 5, 6], c.for_page(2, 3).all()) 190 | self.assertEqual([5, 6], c.for_page(2, 4).all()) 191 | 192 | def test_prepend(self): 193 | c = Collection([4, 5, 6]) 194 | c.prepend(3) 195 | self.assertEqual([3, 4, 5, 6], c.all()) 196 | 197 | def test_append(self): 198 | c = Collection([3, 4, 5]) 199 | c.append(6) 200 | self.assertEqual([3, 4, 5, 6], c.all()) 201 | 202 | def test_pull(self): 203 | c = Collection([1, 2, 3, 4]) 204 | c.pull(2) 205 | self.assertEqual([1, 2, 4], c.all()) 206 | 207 | def test_put(self): 208 | c = Collection([1, 2, 4]) 209 | c.put(2, 3) 210 | self.assertEqual([1, 2, 3], c.all()) 211 | 212 | def test_reject(self): 213 | c = Collection([1, 2, 3, 4, 5, 6]) 214 | self.assertEqual([1, 2, 3], c.reject(lambda x: x > 3).all()) 215 | 216 | def test_reverse(self): 217 | c = Collection([1, 2, 3, 4]) 218 | self.assertEqual([4, 3, 2, 1], c.reverse().all()) 219 | 220 | def test_sort(self): 221 | c = Collection([5, 3, 1, 2, 4]) 222 | 223 | sorted = c.sort(lambda x: x) 224 | self.assertEqual([1, 2, 3, 4, 5], sorted.all()) 225 | 226 | def test_take(self): 227 | c = Collection([1, 2, 3, 4, 5, 6]) 228 | self.assertEqual([1, 2, 3], c.take(3).all()) 229 | self.assertEqual([4, 5, 6], c.take(-3).all()) 230 | 231 | def test_transform(self): 232 | c = Collection([1, 2, 3, 4]) 233 | c.transform(lambda x: x + 2) 234 | self.assertEqual([3, 4, 5, 6], c.all()) 235 | 236 | def test_zip(self): 237 | c = Collection([1, 2, 3]) 238 | self.assertEqual([(1, 4), (2, 5), (3, 6)], c.zip([4, 5, 6]).all()) 239 | 240 | def test_only(self): 241 | c = Collection([1, 2, 3, 4, 5]) 242 | self.assertEqual([2, 4], c.only(1, 3).all()) 243 | 244 | def test_without(self): 245 | c = Collection([1, 2, 3, 4, 5]) 246 | self.assertEqual([1, 3, 5], c.without(1, 3).all()) 247 | self.assertEqual([1, 2, 3, 4, 5], c.all()) 248 | 249 | def test_flatten(self): 250 | c = Collection({'foo': [5, 6], 'bar': 7, 'baz': {'boom': [1, 2, 3, 4]}}) 251 | 252 | self.assertEqual( 253 | [1, 2, 3, 4, 5, 6, 7], 254 | c.flatten().sort().all() 255 | ) 256 | 257 | c = Collection([1, [2, 3], 4]) 258 | self.assertEqual([1, 2, 3, 4], c.flatten().all()) 259 | -------------------------------------------------------------------------------- /backpack/collections/base_collection.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from __future__ import division 4 | 5 | import simplejson as json 6 | from copy import copy 7 | 8 | from .._utils import reduce, basestring, value, data_get 9 | 10 | 11 | class BaseCollection(object): 12 | 13 | def __init__(self, items=None): 14 | """ 15 | Creates a new Collection 16 | 17 | :param items: The collection items 18 | :param items: The collection itdems 19 | :type items: list or Collection or map 20 | 21 | :rtype: None 22 | """ 23 | if items is None: 24 | items = [] 25 | else: 26 | items = self._get_items(items) 27 | 28 | self._items = items 29 | 30 | @property 31 | def items(self): 32 | return self._items 33 | 34 | @classmethod 35 | def make(cls, items=None): 36 | """ 37 | Create a new Collection instance if the value isn't one already 38 | 39 | :param items: The collection items 40 | :type items: list or Collection 41 | 42 | :return: A Collection instance 43 | :rtype: Collection 44 | """ 45 | if isinstance(items, BaseCollection): 46 | return items 47 | 48 | return cls(items) 49 | 50 | def all(self): 51 | """ 52 | Get all of the items in the collection. 53 | 54 | :return: The items in the collections 55 | :type: mixed 56 | """ 57 | return self.items 58 | 59 | def avg(self, key=None): 60 | """ 61 | Get the average value of a given key. 62 | 63 | :param key: The key to get the average for 64 | :type key: mixed 65 | 66 | :rtype: float or int 67 | """ 68 | count = self.count() 69 | 70 | if count: 71 | return self.sum(key) / count 72 | 73 | def chunk(self, size): 74 | """ 75 | Chunk the underlying collection. 76 | 77 | :param size: The chunk size 78 | :type size: int 79 | 80 | :rtype: Collection 81 | """ 82 | chunks = self._chunk(size) 83 | 84 | return self.__class__(list(map(self.__class__, chunks))) 85 | 86 | def _chunk(self, size): 87 | """ 88 | Chunk the underlying collection. 89 | 90 | :param size: The chunk size 91 | :type size: int 92 | 93 | :rtype: Collection 94 | """ 95 | items = self.items 96 | 97 | return [items[i:i + size] for i in range(0, len(items), size)] 98 | 99 | def count(self): 100 | return len(self._items) 101 | 102 | def contains(self, key, value=None): 103 | """ 104 | Determine if an element is in the collection 105 | 106 | :param key: The element 107 | :type key: int or str or callable 108 | 109 | :param value: The value of the element 110 | :type value: mixed 111 | 112 | :return: Whether the element is in the collection 113 | :rtype: bool 114 | """ 115 | if value is not None: 116 | return self.contains(lambda x: data_get(x, key) == value) 117 | 118 | if self._use_as_callable(key): 119 | return self.first(key) is not None 120 | 121 | return key in self.items 122 | 123 | def collapse(self): 124 | """ 125 | Collapse the collection items into a single element (list) 126 | 127 | :return: A new Collection instance with collapsed items 128 | :rtype: Collection 129 | """ 130 | results = [] 131 | 132 | items = self.items 133 | 134 | for values in items: 135 | if isinstance(values, BaseCollection): 136 | values = values.all() 137 | 138 | results += values 139 | 140 | return self.__class__(results) 141 | 142 | def __contains__(self, item): 143 | return self.contains(item) 144 | 145 | def diff(self, items): 146 | """ 147 | Diff the collections with the given items 148 | 149 | :param items: The items to diff with 150 | :type items: mixed 151 | 152 | :return: A Collection instance 153 | :rtype: Collection 154 | """ 155 | return self.__class__([i for i in self.items if i not in items]) 156 | 157 | def each(self, callback): 158 | """ 159 | Execute a callback over each item. 160 | 161 | .. code:: 162 | 163 | collection = Collection([1, 2, 3]) 164 | collection.each(lambda x: x + 3) 165 | 166 | .. warning:: 167 | 168 | It only applies the callback but does not modify the collection's items. 169 | Use the `transform() <#backpack.Collection.transform>`_ method to 170 | modify the collection. 171 | 172 | :param callback: The callback to execute 173 | :type callback: callable 174 | 175 | :rtype: Collection 176 | """ 177 | items = self.items 178 | 179 | for item in items: 180 | if callback(item) is False: 181 | break 182 | 183 | return self 184 | 185 | def every(self, step, offset=0): 186 | """ 187 | Create a new collection consisting of every n-th element. 188 | 189 | :param step: The step size 190 | :type step: int 191 | 192 | :param offset: The start offset 193 | :type offset: int 194 | 195 | :rtype: Collection 196 | """ 197 | new = [] 198 | 199 | for position, item in enumerate(self.items): 200 | if position % step == offset: 201 | new.append(item) 202 | 203 | return self.__class__(new) 204 | 205 | def without(self, *keys): 206 | """ 207 | Get all items except for those with the specified keys. 208 | 209 | :param keys: The keys to remove 210 | :type keys: tuple 211 | 212 | :rtype: Collection 213 | """ 214 | items = copy(self.items) 215 | 216 | keys = reversed(sorted(keys)) 217 | 218 | for key in keys: 219 | del items[key] 220 | 221 | return self.__class__(items) 222 | 223 | def only(self, *keys): 224 | """ 225 | Get the items with the specified keys. 226 | 227 | :param keys: The keys to keep 228 | :type keys: tuple 229 | 230 | :rtype: Collection 231 | """ 232 | items = [] 233 | 234 | for key, value in enumerate(self.items): 235 | if key in keys: 236 | items.append(value) 237 | 238 | return self.__class__(items) 239 | 240 | def filter(self, callback=None): 241 | """ 242 | Run a filter over each of the items. 243 | 244 | :param callback: The filter callback 245 | :type callback: callable or None 246 | 247 | :rtype: Collection 248 | """ 249 | if callback: 250 | return self.__class__(list(filter(callback, self.items))) 251 | 252 | return self.__class__(list(filter(None, self.items))) 253 | 254 | def where(self, key, value): 255 | """ 256 | Filter items by the given key value pair. 257 | 258 | :param key: The key to filter by 259 | :type key: str 260 | 261 | :param value: The value to filter by 262 | :type value: mixed 263 | 264 | :rtype: Collection 265 | """ 266 | return self.filter(lambda item: data_get(item, key) == value) 267 | 268 | def first(self, callback=None, default=None): 269 | """ 270 | Get the first item of the collection. 271 | 272 | :param default: The default value 273 | :type default: mixed 274 | """ 275 | if callback is not None: 276 | for val in self.items: 277 | if callback(val): 278 | return val 279 | 280 | return value(default) 281 | 282 | if len(self.items) > 0: 283 | return self.items[0] 284 | else: 285 | return default 286 | 287 | def flatten(self): 288 | """ 289 | Get a flattened list of the items in the collection. 290 | 291 | :rtype: Collection 292 | """ 293 | 294 | def _flatten(d): 295 | if isinstance(d, dict): 296 | for v in d.values(): 297 | for nested_v in _flatten(v): 298 | yield nested_v 299 | elif isinstance(d, list): 300 | for list_v in d: 301 | for nested_v in _flatten(list_v): 302 | yield nested_v 303 | else: 304 | yield d 305 | 306 | return self.__class__(list(_flatten(self.items))) 307 | 308 | def forget(self, *keys): 309 | """ 310 | Remove an item from the collection by key. 311 | 312 | :param keys: The keys to remove 313 | :type keys: tuple 314 | 315 | :rtype: Collection 316 | """ 317 | keys = reversed(sorted(keys)) 318 | 319 | for key in keys: 320 | del self[key] 321 | 322 | return self 323 | 324 | def get(self, key, default=None): 325 | """ 326 | Get an element of the collection. 327 | 328 | :param key: The index of the element 329 | :type key: mixed 330 | 331 | :param default: The default value to return 332 | :type default: mixed 333 | 334 | :rtype: mixed 335 | """ 336 | try: 337 | return self.items[key] 338 | except IndexError: 339 | return value(default) 340 | 341 | def implode(self, value, glue=''): 342 | """ 343 | Concatenate values of a given key as a string. 344 | 345 | :param value: The value 346 | :type value: str 347 | 348 | :param glue: The glue 349 | :type glue: str 350 | 351 | :rtype: str 352 | """ 353 | first = self.first() 354 | 355 | if not isinstance(first, (basestring)): 356 | return glue.join(self.pluck(value).all()) 357 | 358 | return value.join(self.items) 359 | 360 | def last(self, callback=None, default=None): 361 | """ 362 | Get the last item of the collection. 363 | 364 | :param default: The default value 365 | :type default: mixed 366 | """ 367 | if callback is not None: 368 | for val in reversed(self.items): 369 | if callback(val): 370 | return val 371 | 372 | return value(default) 373 | 374 | if len(self.items) > 0: 375 | return self.items[-1] 376 | else: 377 | return default 378 | 379 | def pluck(self, value, key=None): 380 | """ 381 | Get a list with the values of a given key. 382 | 383 | :rtype: Collection 384 | """ 385 | if key: 386 | return dict(map(lambda x: (data_get(x, key), data_get(x, value)), self.items)) 387 | else: 388 | results = list(map(lambda x: data_get(x, value), self.items)) 389 | 390 | return self.__class__(results) 391 | 392 | def lists(self, value, key=None): 393 | """ 394 | Alias for "pluck" 395 | 396 | :rtype: list 397 | """ 398 | return self.pluck(value, key) 399 | 400 | def map(self, callback): 401 | """ 402 | Run a map over each of the item. 403 | 404 | :param callback: The map function 405 | :type callback: callable 406 | 407 | :rtype: Collection 408 | """ 409 | return self.__class__(list(map(callback, self.items))) 410 | 411 | def max(self, key=None): 412 | """ 413 | Get the max value of a given key. 414 | 415 | :param key: The key 416 | :type key: str or None 417 | 418 | :rtype: mixed 419 | """ 420 | 421 | def _max(result, item): 422 | val = data_get(item, key) 423 | 424 | if result is None or val > result: 425 | return value 426 | 427 | return result 428 | 429 | return self.reduce(_max) 430 | 431 | def min(self, key=None): 432 | """ 433 | Get the min value of a given key. 434 | 435 | :param key: The key 436 | :type key: str or None 437 | 438 | :rtype: mixed 439 | """ 440 | 441 | def _min(result, item): 442 | val = data_get(item, key) 443 | 444 | if result is None or val < result: 445 | return value 446 | 447 | return result 448 | 449 | return self.reduce(_min) 450 | 451 | def for_page(self, page, per_page): 452 | """ 453 | "Paginate" the collection by slicing it into a smaller collection. 454 | 455 | :param page: The current page 456 | :type page: int 457 | 458 | :param per_page: Number of items by slice 459 | :type per_page: int 460 | 461 | :rtype: Collection 462 | """ 463 | start = (page - 1) * per_page 464 | 465 | return self[start:start + per_page] 466 | 467 | def pop(self, key=None): 468 | """ 469 | Remove the item at the given index, and return it. 470 | If no index is specified, returns the last item. 471 | 472 | :param key: The index of the item to return 473 | :type key: mixed 474 | 475 | :rtype: mixed 476 | """ 477 | if key is None: 478 | key = -1 479 | 480 | return self.items.pop(key) 481 | 482 | def prepend(self, value): 483 | """ 484 | Push an item onto the beginning of the collection. 485 | 486 | :param value: The value to push 487 | :type value: mixed 488 | 489 | :rtype: Collection 490 | """ 491 | self.items.insert(0, value) 492 | 493 | return self 494 | 495 | def append(self, value): 496 | """ 497 | Push an item onto the end of the collection. 498 | 499 | :param value: The value to push 500 | :type value: mixed 501 | 502 | :rtype: Collection 503 | """ 504 | self.items.append(value) 505 | 506 | return self 507 | 508 | def push(self, value): 509 | """ 510 | Alias for append. 511 | 512 | :param value: The value to push 513 | :type value: mixed 514 | 515 | :rtype: Collection 516 | """ 517 | return self.append(value) 518 | 519 | def pull(self, key, default=None): 520 | """ 521 | Pulls an item from the collection. 522 | 523 | :param key: The key 524 | :type key: mixed 525 | 526 | :param default: The default value 527 | :type default: mixed 528 | 529 | :rtype: mixed 530 | """ 531 | val = self.get(key, default) 532 | 533 | self.forget(key) 534 | 535 | return val 536 | 537 | def put(self, key, value): 538 | """ 539 | Put an item in the collection by key. 540 | 541 | :param key: The key 542 | :type key: mixed 543 | 544 | :param value: The value 545 | :type value: mixed 546 | 547 | :rtype: Collection 548 | """ 549 | self[key] = value 550 | 551 | return self 552 | 553 | def reduce(self, callback, initial=None): 554 | """ 555 | Reduce the collection to a single value. 556 | 557 | :param callback: The callback 558 | :type callback: callable 559 | 560 | :param initial: The initial value 561 | :type initial: mixed 562 | 563 | :rtype: mixed 564 | """ 565 | return reduce(callback, self.items, initial) 566 | 567 | def reject(self, callback): 568 | """ 569 | Create a collection of all elements that do not pass a given truth test. 570 | 571 | :param callback: The truth test 572 | :type callback: callable 573 | 574 | :rtype: Collection 575 | """ 576 | if self._use_as_callable(callback): 577 | return self.filter(lambda item: not callback(item)) 578 | 579 | return self.filter(lambda item: item != callback) 580 | 581 | def reverse(self): 582 | """ 583 | Reverse items order. 584 | 585 | :rtype: Collection 586 | """ 587 | return self.__class__(list(reversed(self.items))) 588 | 589 | def shift(self): 590 | """ 591 | Remove first item of the collection, and return it. 592 | 593 | :rtype: mixed 594 | """ 595 | return self.pop(0) 596 | 597 | def sort(self, callback=None): 598 | """ 599 | Sort through each item with a callback. 600 | 601 | :param callback: The callback 602 | :type callback: callable or None 603 | 604 | :rtype: Collection 605 | """ 606 | items = self.items 607 | 608 | if callback: 609 | return self.__class__(sorted(items, key=callback)) 610 | else: 611 | return self.__class__(sorted(items)) 612 | 613 | def sum(self, callback=None): 614 | """ 615 | Get the sum of the given values. 616 | 617 | :param callback: The callback 618 | :type callback: callable or string or None 619 | 620 | :rtype: mixed 621 | """ 622 | if callback is None: 623 | return sum(self.items) 624 | 625 | callback = self._value_retriever(callback) 626 | 627 | return self.reduce(lambda result, item: (result or 0) + callback(item)) 628 | 629 | def take(self, limit): 630 | """ 631 | Take the first or last n items. 632 | 633 | :param limit: The number of items to take 634 | :type limit: int 635 | 636 | :rtype: Collection 637 | """ 638 | if limit < 0: 639 | return self[limit:] 640 | 641 | return self[:limit] 642 | 643 | def unique(self, key=None): 644 | """ 645 | Return only unique items from the collection list. 646 | 647 | :param key: The key to chech uniqueness on 648 | :type key: mixed 649 | 650 | :rtype: Collection 651 | """ 652 | if key is None: 653 | seen = set() 654 | seen_add = seen.add 655 | 656 | return self.__class__([x for x in self.items if not (x in seen or seen_add(x))]) 657 | 658 | key = self._value_retriever(key) 659 | 660 | exists = [] 661 | 662 | def _check(item): 663 | id_ = key(item) 664 | if id_ in exists: 665 | return True 666 | 667 | exists.append(id_) 668 | 669 | return self.reject(_check) 670 | 671 | def values(self): 672 | """ 673 | Return collection values. 674 | 675 | :rtype: Collection 676 | """ 677 | return self 678 | 679 | def keys(self): 680 | """ 681 | Return collection keys. 682 | 683 | :rtype: Collection 684 | """ 685 | return self 686 | 687 | def zip(self, *items): 688 | """ 689 | Zip the collection together with one or more arrays. 690 | 691 | :param items: The items to zip 692 | :type items: list 693 | 694 | :rtype: Collection 695 | """ 696 | return self.__class__(list(zip(self.items, *items))) 697 | 698 | def is_empty(self): 699 | return len(self) == 0 700 | 701 | def merge(self, items): 702 | """ 703 | Merge the collection with the given items. 704 | 705 | :param items: The items to merge 706 | :type items: list or Collection 707 | 708 | :rtype: Collection 709 | """ 710 | if isinstance(items, BaseCollection): 711 | items = items.all() 712 | 713 | if not isinstance(items, list): 714 | raise ValueError('Unable to merge uncompatible types') 715 | 716 | self._items += items 717 | 718 | return self 719 | 720 | def transform(self, callback): 721 | """ 722 | Transform each item in the collection using a callback. 723 | 724 | :param callback: The callback 725 | :type callback: callable 726 | 727 | :rtype: Collection 728 | """ 729 | self._items = self.map(callback).all() 730 | 731 | return self 732 | 733 | def _value_retriever(self, value): 734 | """ 735 | Get a value retrieving callback. 736 | 737 | :type value: mixed 738 | 739 | :rtype: callable 740 | """ 741 | if self._use_as_callable(value): 742 | return value 743 | 744 | return lambda item: data_get(item, value) 745 | 746 | def _use_as_callable(self, value): 747 | """ 748 | Determine if the given value is callable. 749 | 750 | :type value: mixed 751 | 752 | :rtype: bool 753 | """ 754 | return not isinstance(value, basestring) and callable(value) 755 | 756 | def serialize(self): 757 | """ 758 | Get the collection of items as a serialized object (ready to be json encoded). 759 | 760 | :rtype: dict or list 761 | """ 762 | 763 | def _serialize(value): 764 | if hasattr(value, 'serialize'): 765 | return value.serialize() 766 | elif hasattr(value, 'to_dict'): 767 | return value.to_dict() 768 | else: 769 | return value 770 | 771 | return list(map(_serialize, self.items)) 772 | 773 | def to_json(self, **options): 774 | """ 775 | Get the collection of items as JSON. 776 | 777 | :param options: JSON encoding options: 778 | :type options: dict 779 | 780 | :rtype: str 781 | """ 782 | return json.dumps(self.serialize(), **options) 783 | 784 | def __len__(self): 785 | return len(self.items) 786 | 787 | def __iter__(self): 788 | for item in self.items: 789 | yield item 790 | 791 | def __getitem__(self, item): 792 | if isinstance(item, slice): 793 | return self.__class__.make(self.items[item]) 794 | 795 | return self.items[item] 796 | 797 | def __setitem__(self, key, value): 798 | self.items[key] = value 799 | 800 | def __delitem__(self, key): 801 | del self.items[key] 802 | 803 | def __eq__(self, other): 804 | if isinstance(other, BaseCollection): 805 | other = other.items 806 | 807 | return other == self.items 808 | 809 | def __ne__(self, other): 810 | if isinstance(other, BaseCollection): 811 | other = other.items 812 | 813 | return other != self.items 814 | 815 | def _set_items(self, items): 816 | self._items = items 817 | 818 | def _get_items(self, items): 819 | if isinstance(items, list): 820 | return items 821 | elif isinstance(items, tuple): 822 | return list(items) 823 | elif isinstance(items, BaseCollection): 824 | return items.all() 825 | elif hasattr('items', 'to_list'): 826 | return items.to_list() 827 | 828 | return [items] 829 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Backpack 2 | ######## 3 | 4 | .. image:: https://travis-ci.org/sdispater/backpack.png 5 | :alt: Backpack Build status 6 | :target: https://travis-ci.org/sdispater/backpack 7 | 8 | Useful utilities for Python. 9 | 10 | Supports Python **2.7+** and **3.2+**. 11 | 12 | 13 | Collection 14 | ========== 15 | 16 | The ``Collection`` class provides a fluent, convenient wrapper for working with list of data. 17 | 18 | To instantiatte a ``Collection`` you can also use the ``collect()`` helper. 19 | 20 | 21 | Available Methods 22 | ***************** 23 | 24 | For the remainder of this documentation, we'll discuss each method available on the ``Collection`` class. 25 | Remember, all of these methods may be chained for fluently manipulating the underlying list or dict. 26 | Furthermore, almost every method returns a new ``Collection`` instance, 27 | allowing you to preserve the original copy of the collection when necessary. 28 | 29 | You may select any method from this table to see an example of its usage: 30 | 31 | * all_ 32 | * avg_ 33 | * chunk_ 34 | * collapse_ 35 | * contains_ 36 | * count_ 37 | * diff_ 38 | * each_ 39 | * every_ 40 | * filter_ 41 | * first_ 42 | * flatten_ 43 | * forget_ 44 | * for_page_ 45 | * get_ 46 | * implode_ 47 | * is_empty_ 48 | * last_ 49 | * map_ 50 | * merge_ 51 | * pluck_ 52 | * pop_ 53 | * prepend_ 54 | * pull_ 55 | * push_ 56 | * put_ 57 | * reduce_ 58 | * reject_ 59 | * reverse_ 60 | * serialize_ 61 | * shift_ 62 | * sort_ 63 | * sum_ 64 | * take_ 65 | * to_json_ 66 | * transform_ 67 | * unique_ 68 | * where_ 69 | * zip_ 70 | 71 | 72 | Methods Listing 73 | *************** 74 | 75 | .. _all: 76 | 77 | ``all()`` 78 | --------- 79 | 80 | The ``all`` method simply returns the underlying list represented by the collection: 81 | 82 | .. code-block:: python 83 | 84 | Collection([1, 2, 3]).all() 85 | 86 | # [1, 2, 3] 87 | 88 | 89 | .. _avg: 90 | 91 | ``avg()`` 92 | --------- 93 | 94 | The ``avg`` method returns the average of all items in the collection: 95 | 96 | .. code-block:: python 97 | 98 | Collection([1, 2, 3, 4, 5]).avg() 99 | 100 | # 3 101 | 102 | If the collection contains nested objects or dictionaries, you must pass a key to use for determining 103 | which values to calculate the average: 104 | 105 | .. code-block:: python 106 | 107 | collection = Collection([ 108 | {'name': 'JavaScript: The Good Parts', 'pages': 176}, 109 | {'name': 'JavaScript: The Defnitive Guide', 'pages': 1096} 110 | ]) 111 | 112 | collection.avg('pages') 113 | 114 | # 636 115 | 116 | 117 | .. _chunk: 118 | 119 | ``chunk()`` 120 | ----------- 121 | 122 | The ``chunk`` method breaks the collection into multiple, smaller collections of a given size: 123 | 124 | .. code-block:: python 125 | 126 | collection = Collection([1, 2, 3, 4, 5, 6, 7]) 127 | 128 | chunks = collection.chunk(4) 129 | 130 | chunks.serialize() 131 | 132 | # [[1, 2, 3, 4], [5, 6, 7]] 133 | 134 | 135 | .. _collapse: 136 | 137 | ``collapse()`` 138 | -------------- 139 | 140 | The ``collapse`` method collapses a collection of lists into a flat collection: 141 | 142 | .. code-block:: python 143 | 144 | collection = Collection([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) 145 | 146 | collapsed = collection.collapse() 147 | 148 | collapsed.all() 149 | 150 | # [1, 2, 3, 4, 5, 6, 7, 8, 9] 151 | 152 | 153 | .. _contains: 154 | 155 | ``contains()`` 156 | -------------- 157 | 158 | The ``contains`` method determines whether the collection contains a given item: 159 | 160 | .. code-block:: python 161 | 162 | collection = Collection(['foo', 'bar']) 163 | 164 | collection.contains('foo') 165 | 166 | # True 167 | 168 | You can also use the ``in`` keyword: 169 | 170 | .. code-block:: python 171 | 172 | 'foo' in collection 173 | 174 | # True 175 | 176 | You can also pass a key / value pair to the ``contains`` method, 177 | which will determine if the given pair exists in the collection: 178 | 179 | .. code-block:: python 180 | 181 | collection = Collection([ 182 | {'name': 'John', 'id': 1}, 183 | {'name': 'Jane', 'id': 2} 184 | ]) 185 | 186 | collection.contains('name', 'Simon') 187 | 188 | # False 189 | 190 | Finally, you may also pass a callback to the ``contains`` method to perform your own truth test: 191 | 192 | 193 | .. code-block:: python 194 | 195 | collection = Collection([1, 2, 3, 4, 5]) 196 | 197 | collection.contains(lambda item: item > 5) 198 | 199 | # False 200 | 201 | 202 | .. _count: 203 | 204 | ``count()`` 205 | ----------- 206 | 207 | The ``count`` method returns the total number of items in the collection: 208 | 209 | .. code-block:: python 210 | 211 | collection = Collection([1, 2, 3, 4]) 212 | 213 | collection.count() 214 | 215 | # 4 216 | 217 | The ``len`` function can also be used: 218 | 219 | .. code-block:: python 220 | 221 | len(collection) 222 | 223 | # 4 224 | 225 | 226 | .. _diff: 227 | 228 | ``diff()`` 229 | ---------- 230 | 231 | The ``diff`` method compares the collection against another collection, a ``list`` or a ``dict``: 232 | 233 | .. code-block:: python 234 | 235 | collection = Collection([1, 2, 3, 4, 5]) 236 | 237 | diff = collection.diff([2, 4, 6, 8]) 238 | 239 | diff.all() 240 | 241 | # [1, 3, 5] 242 | 243 | 244 | .. _each: 245 | 246 | ``each()`` 247 | ---------- 248 | 249 | The ``each`` method iterates over the items in the collection and passes each item to a given callback: 250 | 251 | .. code-block:: python 252 | 253 | posts.each(lambda post: post.author().save(author)) 254 | 255 | Return ``False`` from your callback to break out of the loop: 256 | 257 | .. code-block:: python 258 | 259 | posts.each(lambda post: post.author().save(author) if author.name == 'John' else False) 260 | 261 | 262 | .. _every: 263 | 264 | ``every()`` 265 | ----------- 266 | 267 | The ``every`` method creates a new collection consisting of every n-th element: 268 | 269 | .. code-block:: python 270 | 271 | collection = Collection(['a', 'b', 'c', 'd', 'e', 'f']) 272 | 273 | collection.every(4).all() 274 | 275 | # ['a', 'e'] 276 | 277 | You can optionally pass the offset as the second argument: 278 | 279 | 280 | .. code-block:: python 281 | 282 | collection.every(4, 1).all() 283 | 284 | # ['b', 'f'] 285 | 286 | 287 | .. _filter: 288 | 289 | ``filter()`` 290 | ------------ 291 | 292 | The ``filter`` method filters the collection by a given callback, 293 | keeping only those items that pass a given truth test: 294 | 295 | .. code-block:: python 296 | 297 | collection = Collection([1, 2, 3, 4]) 298 | 299 | filtered = collection.filter(lambda item: item > 2) 300 | 301 | filtered.all() 302 | 303 | # [3, 4] 304 | 305 | 306 | .. _first: 307 | 308 | ``first()`` 309 | ----------- 310 | 311 | The ``first`` method returns the first element in the collection 312 | that passes a given truth test: 313 | 314 | .. code-block:: python 315 | 316 | collection = Collection([1, 2, 3, 4]) 317 | 318 | collection.first(lambda item: item > 2) 319 | 320 | # 3 321 | 322 | You can also call the ``first`` method with no arguments 323 | to get the first element in the collection. 324 | If the collection is empty, ``None`` is returned: 325 | 326 | .. code-block:: python 327 | 328 | collection.first() 329 | 330 | # 1 331 | 332 | 333 | .. _flatten: 334 | 335 | ``flatten()`` 336 | ------------- 337 | 338 | The ``flatten`` method flattens a multi-dimensional collection into a single dimension: 339 | 340 | .. code-block:: python 341 | 342 | collection = Collection([1, 2, [3, 4, 5, {'foo': 'bar'}]]) 343 | 344 | flattened = collection.flatten() 345 | 346 | flattened.all() 347 | 348 | # [1, 2, 3, 4, 5, 'bar'] 349 | 350 | 351 | .. _forget: 352 | 353 | ``forget()`` 354 | ------------ 355 | 356 | The ``forget`` method removes an item from the collection by its key: 357 | 358 | .. code-block:: python 359 | 360 | collection = Collection([1, 2, 3, 4, 5]) 361 | 362 | collection.forget(1) 363 | 364 | collection.all() 365 | 366 | # [1, 3, 4, 5] 367 | 368 | .. warning:: 369 | 370 | Unlike most other collection methods, ``forget`` does not return a new modified collection; 371 | it modifies the collection it is called on. 372 | 373 | 374 | .. _for_page: 375 | 376 | ``for_page()`` 377 | -------------- 378 | 379 | The ``for_page`` method returns a new collection containing 380 | the items that would be present on a given page number: 381 | 382 | .. code-block:: python 383 | 384 | collection = Collection([1, 2, 3, 4, 5, 6, 7, 8, 9]) 385 | 386 | chunk = collection.for_page(2, 3) 387 | 388 | chunk.all() 389 | 390 | # 4, 5, 6 391 | 392 | The method requires the page number and the number of items to show per page, respectively. 393 | 394 | 395 | .. _get: 396 | 397 | ``get()`` 398 | --------- 399 | 400 | The ``get`` method returns the item at a given key. If the key does not exist, ``None`` is returned: 401 | 402 | .. code-block:: python 403 | 404 | collection = Collection([1, 2, 3]) 405 | 406 | collection.get(3) 407 | 408 | # None 409 | 410 | You can optionally pass a default value as the second argument: 411 | 412 | .. code-block:: python 413 | 414 | collection = Collection([1, 2, 3]) 415 | 416 | collection.get(3, 'default-value') 417 | 418 | # default-value 419 | 420 | 421 | .. _implode: 422 | 423 | ``implode()`` 424 | ------------- 425 | 426 | The ``implode`` method joins the items in a collection. 427 | Its arguments depend on the type of items in the collection. 428 | 429 | If the collection contains dictionaries or objects, 430 | you must pass the key of the attributes you wish to join, 431 | and the "glue" string you wish to place between the values: 432 | 433 | .. code-block:: python 434 | 435 | collection = Collection([ 436 | {'account_id': 1, 'product': 'Desk'}, 437 | {'account_id': 2, 'product': 'Chair'} 438 | ]) 439 | 440 | collection.implode('product', ', ') 441 | 442 | # Desk, Chair 443 | 444 | If the collection contains simple strings, 445 | simply pass the "glue" as the only argument to the method: 446 | 447 | .. code-block:: python 448 | 449 | collection = Collection(['foo', 'bar', 'baz']) 450 | 451 | collection.implode('-') 452 | 453 | # foo-bar-baz 454 | 455 | 456 | .. _is_empty: 457 | 458 | ``is_empty()`` 459 | -------------- 460 | 461 | The ``is_empty`` method returns ``True`` if the collection is empty; otherwise, ``False`` is returned: 462 | 463 | .. code-block:: python 464 | 465 | Collection([]).is_empty() 466 | 467 | # True 468 | 469 | 470 | .. _last: 471 | 472 | ``last()`` 473 | ---------- 474 | 475 | The ``last`` method returns the last element in the collection that passes a given truth test: 476 | 477 | .. code-block:: python 478 | 479 | collection = Collection([1, 2, 3, 4]) 480 | 481 | last = collection.last(lambda item: item < 3) 482 | 483 | # 2 484 | 485 | You can also call the ``last`` method with no arguments to get the last element in the collection. 486 | If the collection is empty, ``None`` is returned: 487 | 488 | .. code-block:: python 489 | 490 | collection.last() 491 | 492 | # 4 493 | 494 | 495 | .. _map: 496 | 497 | ``map()`` 498 | --------- 499 | 500 | The ``map`` method iterates through the collection and passes each value to the given callback. 501 | The callback is free to modify the item and return it, thus forming a new collection of modified items: 502 | 503 | .. code-block:: python 504 | 505 | collection = Collection([1, 2, 3, 4]) 506 | 507 | multiplied = collection.map(lambda item: item * 2) 508 | 509 | multiplied.all() 510 | 511 | # [2, 4, 6, 8] 512 | 513 | .. warning:: 514 | 515 | Like most other collection methods, ``map`` returns a new ``Collection`` instance; 516 | it does not modify the collection it is called on. 517 | If you want to transform the original collection, use the transform_ method. 518 | 519 | 520 | .. _merge: 521 | 522 | ``merge()`` 523 | ----------- 524 | 525 | The merge method merges the given list into the collection: 526 | 527 | .. code-block:: python 528 | 529 | collection = Collection(['Desk', 'Chair']) 530 | 531 | collection.merge(['Bookcase', 'Door']) 532 | 533 | collection.all() 534 | 535 | # ['Desk', 'Chair', 'Bookcase', 'Door'] 536 | 537 | .. warning:: 538 | 539 | Unlike most other collection methods, ``merge`` does not return a new modified collection; 540 | it modifies the collection it is called on. 541 | 542 | 543 | .. _pluck: 544 | 545 | ``pluck()`` 546 | ----------- 547 | 548 | The ``pluck`` method retrieves all of the collection values for a given key: 549 | 550 | .. code-block:: python 551 | 552 | collection = Collection([ 553 | {'product_id': 1, 'product': 'Desk'}, 554 | {'product_id': 2, 'product': 'Chair'} 555 | ]) 556 | 557 | plucked = collection.pluck('product') 558 | 559 | plucked.all() 560 | 561 | # ['Desk', 'Chair'] 562 | 563 | You can also specify how you wish the resulting collection to be keyed: 564 | 565 | .. code-block:: python 566 | 567 | plucked = collection.pluck('name', 'product_id') 568 | 569 | plucked 570 | 571 | # {1: 'Desk', 2: 'Chair'} 572 | 573 | 574 | .. _pop: 575 | 576 | ``pop()`` 577 | --------- 578 | 579 | The ``pop`` method removes and returns the last item from the collection: 580 | 581 | .. code-block:: python 582 | 583 | collection = Collection([1, 2, 3, 4, 5]) 584 | 585 | collection.pop() 586 | 587 | # 5 588 | 589 | collection.all() 590 | 591 | # [1, 2, 3, 4] 592 | 593 | 594 | .. _prepend: 595 | 596 | ``prepend()`` 597 | ------------- 598 | 599 | The ``prepend`` method adds an item to the beginning of the collection: 600 | 601 | .. code-block:: python 602 | 603 | collection = Collection([1, 2, 3, 4]) 604 | 605 | collection.prepend(0) 606 | 607 | collection.all() 608 | 609 | # [0, 1, 2, 3, 4] 610 | 611 | 612 | .. _pull: 613 | 614 | ``pull()`` 615 | ---------- 616 | 617 | The ``pull`` method removes and returns an item from the collection by its key: 618 | 619 | .. code-block:: python 620 | 621 | collection = Collection([1, 2, 3, 4]) 622 | 623 | collection.pull(1) 624 | 625 | collection.all() 626 | 627 | # [1, 3, 4] 628 | 629 | 630 | .. _push: 631 | 632 | ``push()``/``append()`` 633 | ----------------------- 634 | 635 | The ``push`` (or ``append``) method appends an item to the end of the collection: 636 | 637 | .. code-block:: python 638 | 639 | collection = Collection([1, 2, 3, 4]) 640 | 641 | collection.push(5) 642 | 643 | collection.all() 644 | 645 | # [1, 2, 3, 4, 5] 646 | 647 | 648 | .. _put: 649 | 650 | ``put()`` 651 | --------- 652 | 653 | The ``put`` method sets the given key and value in the collection: 654 | 655 | .. code-block:: python 656 | 657 | collection = Collection([1, 2, 3, 4]) 658 | 659 | collection.put(1, 5) 660 | 661 | collection.all() 662 | 663 | # [1, 5, 3, 4] 664 | 665 | .. note:: 666 | 667 | It is equivalent to: 668 | 669 | .. code-block:: python 670 | 671 | collection[1] = 5 672 | 673 | 674 | .. _reduce: 675 | 676 | ``reduce()`` 677 | ------------ 678 | 679 | The ``reduce`` method reduces the collection to a single value, 680 | passing the result of each iteration into the subsequent iteration: 681 | 682 | .. code-block:: python 683 | 684 | collection = Collection([1, 2, 3]) 685 | 686 | collection.reduce(lambda result, item: (result or 0) + item) 687 | 688 | # 6 689 | 690 | The value for ``result`` on the first iteration is ``None``; 691 | however, you can specify its initial value by passing a second argument to reduce: 692 | 693 | .. code-block:: python 694 | 695 | collection.reduce(lambda result, item: result + item, 4) 696 | 697 | # 10 698 | 699 | 700 | .. _reject: 701 | 702 | ``reject()`` 703 | ------------ 704 | 705 | The ``reject`` method filters the collection using the given callback. 706 | The callback should return ``True`` for any items it wishes to remove from the resulting collection: 707 | 708 | .. code-block:: python 709 | 710 | collection = Collection([1, 2, 3, 4]) 711 | 712 | filtered = collection.reject(lambda item: item > 2) 713 | 714 | filtered.all() 715 | 716 | # [1, 2] 717 | 718 | For the inverse of ``reject``, see the filter_ method. 719 | 720 | 721 | .. _reverse: 722 | 723 | ``reverse()`` 724 | ------------- 725 | 726 | The ``reverse`` method reverses the order of the collection's items: 727 | 728 | .. code-block:: python 729 | 730 | collection = Collection([1, 2, 3, 4, 5]) 731 | 732 | reverse = collection.reverse() 733 | 734 | reverse.all() 735 | 736 | # [5, 4, 3, 2, 1] 737 | 738 | 739 | .. _serialize: 740 | 741 | ``serialize()`` 742 | --------------- 743 | 744 | The ``serialize`` method converts the collection into a ``list``. 745 | If the collection's values are :ref:`ORM` models, the models will also be converted to dictionaries: 746 | 747 | .. code-block:: python 748 | 749 | collection = Collection([User.find(1)]) 750 | 751 | collection.serialize() 752 | 753 | # [{'id': 1, 'name': 'John'}] 754 | 755 | .. warning:: 756 | 757 | ``serialize`` also converts all of its nested objects. 758 | If you want to get the underlying items as is, use the all_ method instead. 759 | 760 | 761 | .. _shift: 762 | 763 | ``shift()`` 764 | ----------- 765 | 766 | The ``shift`` method removes and returns the first item from the collection: 767 | 768 | .. code-block:: python 769 | 770 | collection = Collection([1, 2, 3, 4, 5]) 771 | 772 | collection.shift() 773 | 774 | # 1 775 | 776 | collection.all() 777 | 778 | # [2, 3, 4, 5] 779 | 780 | 781 | .. _sort: 782 | 783 | ``sort()`` 784 | ---------- 785 | 786 | The ``sort`` method sorts the collection: 787 | 788 | .. code-block:: python 789 | 790 | collection = Collection([5, 3, 1, 2, 4]) 791 | 792 | sorted = collection.sort() 793 | 794 | sorted.all() 795 | 796 | # [1, 2, 3, 4, 5] 797 | 798 | 799 | .. _sum: 800 | 801 | ``sum()`` 802 | --------- 803 | 804 | The ``sum`` method returns the sum of all items in the collection: 805 | 806 | .. code-block:: python 807 | 808 | Collection([1, 2, 3, 4, 5]).sum() 809 | 810 | # 15 811 | 812 | If the collection contains dictionaries or objects, you must pass a key to use for determining which values to sum: 813 | 814 | .. code-block:: python 815 | 816 | collection = Collection([ 817 | {'name': 'JavaScript: The Good Parts', 'pages': 176}, 818 | {'name': 'JavaScript: The Defnitive Guide', 'pages': 1096} 819 | ]) 820 | 821 | collection.sum('pages') 822 | 823 | # 1272 824 | 825 | In addition, you can pass your own callback to determine which values of the collection to sum: 826 | 827 | .. code-block:: python 828 | 829 | collection = Collection([ 830 | {'name': 'Chair', 'colors': ['Black']}, 831 | {'name': 'Desk', 'colors': ['Black', 'Mahogany']}, 832 | {'name': 'Bookcase', 'colors': ['Red', 'Beige', 'Brown']} 833 | ]) 834 | 835 | collection.sum(lambda product: len(product['colors'])) 836 | 837 | # 6 838 | 839 | 840 | .. _take: 841 | 842 | ``take()`` 843 | ---------- 844 | 845 | The ``take`` method returns a new collection with the specified number of items: 846 | 847 | .. code-block:: python 848 | 849 | collection = Collection([0, 1, 2, 3, 4, 5]) 850 | 851 | chunk = collection.take(3) 852 | 853 | chunk.all() 854 | 855 | # [0, 1, 2] 856 | 857 | You can also pass a negative integer to take the specified amount of items from the end of the collection: 858 | 859 | .. code-block:: python 860 | 861 | chunk = collection.chunk(-2) 862 | 863 | chunk.all() 864 | 865 | # [4, 5] 866 | 867 | 868 | .. _to_json: 869 | 870 | ``to_json()`` 871 | ------------- 872 | 873 | The ``to_json`` method converts the collection into JSON: 874 | 875 | .. code-block:: python 876 | 877 | collection = Collection([{'name': 'Desk', 'price': 200}]) 878 | 879 | collection.to_json() 880 | 881 | # '[{"name": "Desk", "price": 200}]' 882 | 883 | 884 | .. _transform: 885 | 886 | ``transform()`` 887 | --------------- 888 | 889 | The ``transform`` method iterates over the collection and calls the given callback 890 | with each item in the collection. 891 | The items in the collection will be replaced by the values returned by the callback: 892 | 893 | .. code-block:: python 894 | 895 | collection = Collection([1, 2, 3, 4, 5]) 896 | 897 | collection.transform(lambda item: item * 2) 898 | 899 | collection.all() 900 | 901 | # [2, 4, 6, 8, 10] 902 | 903 | .. warning:: 904 | 905 | Unlike most other collection methods, ``transform`` modifies the collection itself. 906 | If you wish to create a new collection instead, use the map_ method. 907 | 908 | 909 | .. _unique: 910 | 911 | ``unique()`` 912 | ------------ 913 | 914 | The ``unique`` method returns all of the unique items in the collection: 915 | 916 | .. code-block:: python 917 | 918 | collection = Collection([1, 1, 2, 2, 3, 4, 2]) 919 | 920 | unique = collection.unique() 921 | 922 | unique.all() 923 | 924 | # [1, 2, 3, 4] 925 | 926 | When dealing with dictionaries or objects, you can specify the key used to determine uniqueness: 927 | 928 | .. code-block:: python 929 | 930 | collection = Collection([ 931 | {'name': 'iPhone 6', 'brand': 'Apple', 'type': 'phone'}, 932 | {'name': 'iPhone 5', 'brand': 'Apple', 'type': 'phone'}, 933 | {'name': 'Apple Watch', 'brand': 'Apple', 'type': 'watch'}, 934 | {'name': 'Galaxy S6', 'brand': 'Samsung', 'type': 'phone'}, 935 | {'name': 'Galaxy Gear', 'brand': 'Samsung', 'type': 'watch'} 936 | ]) 937 | 938 | unique = collection.unique('brand') 939 | 940 | unique.all() 941 | 942 | # [ 943 | # {'name': 'iPhone 6', 'brand': 'Apple', 'type': 'phone'}, 944 | # {'name': 'Galaxy S6', 'brand': 'Samsung', 'type': 'phone'} 945 | # ] 946 | 947 | You can also pass your own callback to determine item uniqueness: 948 | 949 | .. code-block:: python 950 | 951 | unique = collection.unique(lambda item: item['brand'] + item['type']) 952 | 953 | unique.all() 954 | 955 | # [ 956 | # {'name': 'iPhone 6', 'brand': 'Apple', 'type': 'phone'}, 957 | # {'name': 'Apple Watch', 'brand': 'Apple', 'type': 'watch'}, 958 | # {'name': 'Galaxy S6', 'brand': 'Samsung', 'type': 'phone'}, 959 | # {'name': 'Galaxy Gear', 'brand': 'Samsung', 'type': 'watch'} 960 | # ] 961 | 962 | 963 | .. _where: 964 | 965 | ``where()`` 966 | ----------- 967 | 968 | The ``where`` method filters the collection by a given key / value pair: 969 | 970 | .. code-block:: python 971 | 972 | collection = Collection([ 973 | {'name': 'Desk', 'price': 200}, 974 | {'name': 'Chair', 'price': 100}, 975 | {'name': 'Bookcase', 'price': 150}, 976 | {'name': 'Door', 'price': 100}, 977 | ]) 978 | 979 | filtered = collection.where('price', 100) 980 | 981 | filtered.all() 982 | 983 | # [ 984 | # {'name': 'Chair', 'price': 100}, 985 | # {'name': 'Door', 'price': 100} 986 | # ] 987 | 988 | 989 | .. _zip: 990 | 991 | ``zip()`` 992 | --------- 993 | 994 | The ``zip`` method merges together the values of the given list 995 | with the values of the collection at the corresponding index: 996 | 997 | .. code-block:: python 998 | 999 | collection = Collection(['Chair', 'Desk']) 1000 | 1001 | zipped = collection.zip([100, 200]) 1002 | 1003 | zipped.all() 1004 | 1005 | # [('Chair', 100), ('Desk', 200)] 1006 | -------------------------------------------------------------------------------- /backpack/_utils/_helpers.c: -------------------------------------------------------------------------------- 1 | /* Generated by Cython 0.24.1 */ 2 | 3 | #define PY_SSIZE_T_CLEAN 4 | #include "Python.h" 5 | #ifndef Py_PYTHON_H 6 | #error Python headers needed to compile C extensions, please install development version of Python. 7 | #elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03020000) 8 | #error Cython requires Python 2.6+ or Python 3.2+. 9 | #else 10 | #define CYTHON_ABI "0_24_1" 11 | #include 12 | #ifndef offsetof 13 | #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) 14 | #endif 15 | #if !defined(WIN32) && !defined(MS_WINDOWS) 16 | #ifndef __stdcall 17 | #define __stdcall 18 | #endif 19 | #ifndef __cdecl 20 | #define __cdecl 21 | #endif 22 | #ifndef __fastcall 23 | #define __fastcall 24 | #endif 25 | #endif 26 | #ifndef DL_IMPORT 27 | #define DL_IMPORT(t) t 28 | #endif 29 | #ifndef DL_EXPORT 30 | #define DL_EXPORT(t) t 31 | #endif 32 | #ifndef PY_LONG_LONG 33 | #define PY_LONG_LONG LONG_LONG 34 | #endif 35 | #ifndef Py_HUGE_VAL 36 | #define Py_HUGE_VAL HUGE_VAL 37 | #endif 38 | #ifdef PYPY_VERSION 39 | #define CYTHON_COMPILING_IN_PYPY 1 40 | #define CYTHON_COMPILING_IN_CPYTHON 0 41 | #else 42 | #define CYTHON_COMPILING_IN_PYPY 0 43 | #define CYTHON_COMPILING_IN_CPYTHON 1 44 | #endif 45 | #if !defined(CYTHON_USE_PYLONG_INTERNALS) && CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x02070000 46 | #define CYTHON_USE_PYLONG_INTERNALS 1 47 | #endif 48 | #if CYTHON_USE_PYLONG_INTERNALS 49 | #include "longintrepr.h" 50 | #undef SHIFT 51 | #undef BASE 52 | #undef MASK 53 | #endif 54 | #if CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x02070600 && !defined(Py_OptimizeFlag) 55 | #define Py_OptimizeFlag 0 56 | #endif 57 | #define __PYX_BUILD_PY_SSIZE_T "n" 58 | #define CYTHON_FORMAT_SSIZE_T "z" 59 | #if PY_MAJOR_VERSION < 3 60 | #define __Pyx_BUILTIN_MODULE_NAME "__builtin__" 61 | #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ 62 | PyCode_New(a+k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) 63 | #define __Pyx_DefaultClassType PyClass_Type 64 | #else 65 | #define __Pyx_BUILTIN_MODULE_NAME "builtins" 66 | #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ 67 | PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) 68 | #define __Pyx_DefaultClassType PyType_Type 69 | #endif 70 | #ifndef Py_TPFLAGS_CHECKTYPES 71 | #define Py_TPFLAGS_CHECKTYPES 0 72 | #endif 73 | #ifndef Py_TPFLAGS_HAVE_INDEX 74 | #define Py_TPFLAGS_HAVE_INDEX 0 75 | #endif 76 | #ifndef Py_TPFLAGS_HAVE_NEWBUFFER 77 | #define Py_TPFLAGS_HAVE_NEWBUFFER 0 78 | #endif 79 | #ifndef Py_TPFLAGS_HAVE_FINALIZE 80 | #define Py_TPFLAGS_HAVE_FINALIZE 0 81 | #endif 82 | #if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_KIND) 83 | #define CYTHON_PEP393_ENABLED 1 84 | #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ 85 | 0 : _PyUnicode_Ready((PyObject *)(op))) 86 | #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u) 87 | #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) 88 | #define __Pyx_PyUnicode_KIND(u) PyUnicode_KIND(u) 89 | #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) 90 | #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) 91 | #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) 92 | #else 93 | #define CYTHON_PEP393_ENABLED 0 94 | #define __Pyx_PyUnicode_READY(op) (0) 95 | #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u) 96 | #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i])) 97 | #define __Pyx_PyUnicode_KIND(u) (sizeof(Py_UNICODE)) 98 | #define __Pyx_PyUnicode_DATA(u) ((void*)PyUnicode_AS_UNICODE(u)) 99 | #define __Pyx_PyUnicode_READ(k, d, i) ((void)(k), (Py_UCS4)(((Py_UNICODE*)d)[i])) 100 | #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_SIZE(u)) 101 | #endif 102 | #if CYTHON_COMPILING_IN_PYPY 103 | #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) 104 | #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) 105 | #else 106 | #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) 107 | #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ 108 | PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) 109 | #endif 110 | #if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_Contains) 111 | #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) 112 | #endif 113 | #if CYTHON_COMPILING_IN_PYPY && !defined(PyByteArray_Check) 114 | #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) 115 | #endif 116 | #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Format) 117 | #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) 118 | #endif 119 | #if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) 120 | #define PyObject_Malloc(s) PyMem_Malloc(s) 121 | #define PyObject_Free(p) PyMem_Free(p) 122 | #define PyObject_Realloc(p) PyMem_Realloc(p) 123 | #endif 124 | #define __Pyx_PyString_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : __Pyx_PyString_Format(a, b)) 125 | #define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None)) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) 126 | #if PY_MAJOR_VERSION >= 3 127 | #define __Pyx_PyString_Format(a, b) PyUnicode_Format(a, b) 128 | #else 129 | #define __Pyx_PyString_Format(a, b) PyString_Format(a, b) 130 | #endif 131 | #if PY_MAJOR_VERSION < 3 && !defined(PyObject_ASCII) 132 | #define PyObject_ASCII(o) PyObject_Repr(o) 133 | #endif 134 | #if PY_MAJOR_VERSION >= 3 135 | #define PyBaseString_Type PyUnicode_Type 136 | #define PyStringObject PyUnicodeObject 137 | #define PyString_Type PyUnicode_Type 138 | #define PyString_Check PyUnicode_Check 139 | #define PyString_CheckExact PyUnicode_CheckExact 140 | #endif 141 | #if PY_MAJOR_VERSION >= 3 142 | #define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj) 143 | #define __Pyx_PyBaseString_CheckExact(obj) PyUnicode_CheckExact(obj) 144 | #else 145 | #define __Pyx_PyBaseString_Check(obj) (PyString_Check(obj) || PyUnicode_Check(obj)) 146 | #define __Pyx_PyBaseString_CheckExact(obj) (PyString_CheckExact(obj) || PyUnicode_CheckExact(obj)) 147 | #endif 148 | #ifndef PySet_CheckExact 149 | #define PySet_CheckExact(obj) (Py_TYPE(obj) == &PySet_Type) 150 | #endif 151 | #define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) 152 | #if PY_MAJOR_VERSION >= 3 153 | #define PyIntObject PyLongObject 154 | #define PyInt_Type PyLong_Type 155 | #define PyInt_Check(op) PyLong_Check(op) 156 | #define PyInt_CheckExact(op) PyLong_CheckExact(op) 157 | #define PyInt_FromString PyLong_FromString 158 | #define PyInt_FromUnicode PyLong_FromUnicode 159 | #define PyInt_FromLong PyLong_FromLong 160 | #define PyInt_FromSize_t PyLong_FromSize_t 161 | #define PyInt_FromSsize_t PyLong_FromSsize_t 162 | #define PyInt_AsLong PyLong_AsLong 163 | #define PyInt_AS_LONG PyLong_AS_LONG 164 | #define PyInt_AsSsize_t PyLong_AsSsize_t 165 | #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask 166 | #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask 167 | #define PyNumber_Int PyNumber_Long 168 | #endif 169 | #if PY_MAJOR_VERSION >= 3 170 | #define PyBoolObject PyLongObject 171 | #endif 172 | #if PY_MAJOR_VERSION >= 3 && CYTHON_COMPILING_IN_PYPY 173 | #ifndef PyUnicode_InternFromString 174 | #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) 175 | #endif 176 | #endif 177 | #if PY_VERSION_HEX < 0x030200A4 178 | typedef long Py_hash_t; 179 | #define __Pyx_PyInt_FromHash_t PyInt_FromLong 180 | #define __Pyx_PyInt_AsHash_t PyInt_AsLong 181 | #else 182 | #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t 183 | #define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t 184 | #endif 185 | #if PY_MAJOR_VERSION >= 3 186 | #define __Pyx_PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func)) 187 | #else 188 | #define __Pyx_PyMethod_New(func, self, klass) PyMethod_New(func, self, klass) 189 | #endif 190 | #if PY_VERSION_HEX >= 0x030500B1 191 | #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods 192 | #define __Pyx_PyType_AsAsync(obj) (Py_TYPE(obj)->tp_as_async) 193 | #elif CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 194 | typedef struct { 195 | unaryfunc am_await; 196 | unaryfunc am_aiter; 197 | unaryfunc am_anext; 198 | } __Pyx_PyAsyncMethodsStruct; 199 | #define __Pyx_PyType_AsAsync(obj) ((__Pyx_PyAsyncMethodsStruct*) (Py_TYPE(obj)->tp_reserved)) 200 | #else 201 | #define __Pyx_PyType_AsAsync(obj) NULL 202 | #endif 203 | #ifndef CYTHON_RESTRICT 204 | #if defined(__GNUC__) 205 | #define CYTHON_RESTRICT __restrict__ 206 | #elif defined(_MSC_VER) && _MSC_VER >= 1400 207 | #define CYTHON_RESTRICT __restrict 208 | #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 209 | #define CYTHON_RESTRICT restrict 210 | #else 211 | #define CYTHON_RESTRICT 212 | #endif 213 | #endif 214 | #define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) 215 | 216 | #ifndef CYTHON_INLINE 217 | #if defined(__GNUC__) 218 | #define CYTHON_INLINE __inline__ 219 | #elif defined(_MSC_VER) 220 | #define CYTHON_INLINE __inline 221 | #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 222 | #define CYTHON_INLINE inline 223 | #else 224 | #define CYTHON_INLINE 225 | #endif 226 | #endif 227 | 228 | #if defined(WIN32) || defined(MS_WINDOWS) 229 | #define _USE_MATH_DEFINES 230 | #endif 231 | #include 232 | #ifdef NAN 233 | #define __PYX_NAN() ((float) NAN) 234 | #else 235 | static CYTHON_INLINE float __PYX_NAN() { 236 | float value; 237 | memset(&value, 0xFF, sizeof(value)); 238 | return value; 239 | } 240 | #endif 241 | #if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) 242 | #define __Pyx_truncl trunc 243 | #else 244 | #define __Pyx_truncl truncl 245 | #endif 246 | 247 | 248 | #define __PYX_ERR(f_index, lineno, Ln_error) \ 249 | { \ 250 | __pyx_filename = __pyx_f[f_index]; __pyx_lineno = lineno; __pyx_clineno = __LINE__; goto Ln_error; \ 251 | } 252 | 253 | #if PY_MAJOR_VERSION >= 3 254 | #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) 255 | #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) 256 | #else 257 | #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y) 258 | #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y) 259 | #endif 260 | 261 | #ifndef __PYX_EXTERN_C 262 | #ifdef __cplusplus 263 | #define __PYX_EXTERN_C extern "C" 264 | #else 265 | #define __PYX_EXTERN_C extern 266 | #endif 267 | #endif 268 | 269 | #define __PYX_HAVE__backpack___utils___helpers 270 | #define __PYX_HAVE_API__backpack___utils___helpers 271 | #ifdef _OPENMP 272 | #include 273 | #endif /* _OPENMP */ 274 | 275 | #ifdef PYREX_WITHOUT_ASSERTIONS 276 | #define CYTHON_WITHOUT_ASSERTIONS 277 | #endif 278 | 279 | #ifndef CYTHON_UNUSED 280 | # if defined(__GNUC__) 281 | # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) 282 | # define CYTHON_UNUSED __attribute__ ((__unused__)) 283 | # else 284 | # define CYTHON_UNUSED 285 | # endif 286 | # elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) 287 | # define CYTHON_UNUSED __attribute__ ((__unused__)) 288 | # else 289 | # define CYTHON_UNUSED 290 | # endif 291 | #endif 292 | #ifndef CYTHON_NCP_UNUSED 293 | # if CYTHON_COMPILING_IN_CPYTHON 294 | # define CYTHON_NCP_UNUSED 295 | # else 296 | # define CYTHON_NCP_UNUSED CYTHON_UNUSED 297 | # endif 298 | #endif 299 | typedef struct {PyObject **p; const char *s; const Py_ssize_t n; const char* encoding; 300 | const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; 301 | 302 | #define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 303 | #define __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 0 304 | #define __PYX_DEFAULT_STRING_ENCODING "" 305 | #define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString 306 | #define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize 307 | #define __Pyx_uchar_cast(c) ((unsigned char)c) 308 | #define __Pyx_long_cast(x) ((long)x) 309 | #define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ 310 | (sizeof(type) < sizeof(Py_ssize_t)) ||\ 311 | (sizeof(type) > sizeof(Py_ssize_t) &&\ 312 | likely(v < (type)PY_SSIZE_T_MAX ||\ 313 | v == (type)PY_SSIZE_T_MAX) &&\ 314 | (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ 315 | v == (type)PY_SSIZE_T_MIN))) ||\ 316 | (sizeof(type) == sizeof(Py_ssize_t) &&\ 317 | (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ 318 | v == (type)PY_SSIZE_T_MAX))) ) 319 | #if defined (__cplusplus) && __cplusplus >= 201103L 320 | #include 321 | #define __Pyx_sst_abs(value) std::abs(value) 322 | #elif SIZEOF_INT >= SIZEOF_SIZE_T 323 | #define __Pyx_sst_abs(value) abs(value) 324 | #elif SIZEOF_LONG >= SIZEOF_SIZE_T 325 | #define __Pyx_sst_abs(value) labs(value) 326 | #elif defined (_MSC_VER) && defined (_M_X64) 327 | #define __Pyx_sst_abs(value) _abs64(value) 328 | #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 329 | #define __Pyx_sst_abs(value) llabs(value) 330 | #elif defined (__GNUC__) 331 | #define __Pyx_sst_abs(value) __builtin_llabs(value) 332 | #else 333 | #define __Pyx_sst_abs(value) ((value<0) ? -value : value) 334 | #endif 335 | static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject*); 336 | static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); 337 | #define __Pyx_PyByteArray_FromString(s) PyByteArray_FromStringAndSize((const char*)s, strlen((const char*)s)) 338 | #define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) 339 | #define __Pyx_PyBytes_FromString PyBytes_FromString 340 | #define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize 341 | static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); 342 | #if PY_MAJOR_VERSION < 3 343 | #define __Pyx_PyStr_FromString __Pyx_PyBytes_FromString 344 | #define __Pyx_PyStr_FromStringAndSize __Pyx_PyBytes_FromStringAndSize 345 | #else 346 | #define __Pyx_PyStr_FromString __Pyx_PyUnicode_FromString 347 | #define __Pyx_PyStr_FromStringAndSize __Pyx_PyUnicode_FromStringAndSize 348 | #endif 349 | #define __Pyx_PyObject_AsSString(s) ((signed char*) __Pyx_PyObject_AsString(s)) 350 | #define __Pyx_PyObject_AsUString(s) ((unsigned char*) __Pyx_PyObject_AsString(s)) 351 | #define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) 352 | #define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) 353 | #define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) 354 | #define __Pyx_PyStr_FromCString(s) __Pyx_PyStr_FromString((const char*)s) 355 | #define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) 356 | #if PY_MAJOR_VERSION < 3 357 | static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) 358 | { 359 | const Py_UNICODE *u_end = u; 360 | while (*u_end++) ; 361 | return (size_t)(u_end - u - 1); 362 | } 363 | #else 364 | #define __Pyx_Py_UNICODE_strlen Py_UNICODE_strlen 365 | #endif 366 | #define __Pyx_PyUnicode_FromUnicode(u) PyUnicode_FromUnicode(u, __Pyx_Py_UNICODE_strlen(u)) 367 | #define __Pyx_PyUnicode_FromUnicodeAndLength PyUnicode_FromUnicode 368 | #define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode 369 | #define __Pyx_NewRef(obj) (Py_INCREF(obj), obj) 370 | #define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None) 371 | #define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False)) 372 | static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); 373 | static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); 374 | static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); 375 | static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); 376 | #if CYTHON_COMPILING_IN_CPYTHON 377 | #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) 378 | #else 379 | #define __pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) 380 | #endif 381 | #define __pyx_PyFloat_AsFloat(x) ((float) __pyx_PyFloat_AsDouble(x)) 382 | #if PY_MAJOR_VERSION >= 3 383 | #define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) 384 | #else 385 | #define __Pyx_PyNumber_Int(x) (PyInt_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Int(x)) 386 | #endif 387 | #define __Pyx_PyNumber_Float(x) (PyFloat_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Float(x)) 388 | #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 389 | static int __Pyx_sys_getdefaultencoding_not_ascii; 390 | static int __Pyx_init_sys_getdefaultencoding_params(void) { 391 | PyObject* sys; 392 | PyObject* default_encoding = NULL; 393 | PyObject* ascii_chars_u = NULL; 394 | PyObject* ascii_chars_b = NULL; 395 | const char* default_encoding_c; 396 | sys = PyImport_ImportModule("sys"); 397 | if (!sys) goto bad; 398 | default_encoding = PyObject_CallMethod(sys, (char*) "getdefaultencoding", NULL); 399 | Py_DECREF(sys); 400 | if (!default_encoding) goto bad; 401 | default_encoding_c = PyBytes_AsString(default_encoding); 402 | if (!default_encoding_c) goto bad; 403 | if (strcmp(default_encoding_c, "ascii") == 0) { 404 | __Pyx_sys_getdefaultencoding_not_ascii = 0; 405 | } else { 406 | char ascii_chars[128]; 407 | int c; 408 | for (c = 0; c < 128; c++) { 409 | ascii_chars[c] = c; 410 | } 411 | __Pyx_sys_getdefaultencoding_not_ascii = 1; 412 | ascii_chars_u = PyUnicode_DecodeASCII(ascii_chars, 128, NULL); 413 | if (!ascii_chars_u) goto bad; 414 | ascii_chars_b = PyUnicode_AsEncodedString(ascii_chars_u, default_encoding_c, NULL); 415 | if (!ascii_chars_b || !PyBytes_Check(ascii_chars_b) || memcmp(ascii_chars, PyBytes_AS_STRING(ascii_chars_b), 128) != 0) { 416 | PyErr_Format( 417 | PyExc_ValueError, 418 | "This module compiled with c_string_encoding=ascii, but default encoding '%.200s' is not a superset of ascii.", 419 | default_encoding_c); 420 | goto bad; 421 | } 422 | Py_DECREF(ascii_chars_u); 423 | Py_DECREF(ascii_chars_b); 424 | } 425 | Py_DECREF(default_encoding); 426 | return 0; 427 | bad: 428 | Py_XDECREF(default_encoding); 429 | Py_XDECREF(ascii_chars_u); 430 | Py_XDECREF(ascii_chars_b); 431 | return -1; 432 | } 433 | #endif 434 | #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT && PY_MAJOR_VERSION >= 3 435 | #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) 436 | #else 437 | #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) 438 | #if __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT 439 | static char* __PYX_DEFAULT_STRING_ENCODING; 440 | static int __Pyx_init_sys_getdefaultencoding_params(void) { 441 | PyObject* sys; 442 | PyObject* default_encoding = NULL; 443 | char* default_encoding_c; 444 | sys = PyImport_ImportModule("sys"); 445 | if (!sys) goto bad; 446 | default_encoding = PyObject_CallMethod(sys, (char*) (const char*) "getdefaultencoding", NULL); 447 | Py_DECREF(sys); 448 | if (!default_encoding) goto bad; 449 | default_encoding_c = PyBytes_AsString(default_encoding); 450 | if (!default_encoding_c) goto bad; 451 | __PYX_DEFAULT_STRING_ENCODING = (char*) malloc(strlen(default_encoding_c)); 452 | if (!__PYX_DEFAULT_STRING_ENCODING) goto bad; 453 | strcpy(__PYX_DEFAULT_STRING_ENCODING, default_encoding_c); 454 | Py_DECREF(default_encoding); 455 | return 0; 456 | bad: 457 | Py_XDECREF(default_encoding); 458 | return -1; 459 | } 460 | #endif 461 | #endif 462 | 463 | 464 | /* Test for GCC > 2.95 */ 465 | #if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) 466 | #define likely(x) __builtin_expect(!!(x), 1) 467 | #define unlikely(x) __builtin_expect(!!(x), 0) 468 | #else /* !__GNUC__ or GCC < 2.95 */ 469 | #define likely(x) (x) 470 | #define unlikely(x) (x) 471 | #endif /* __GNUC__ */ 472 | 473 | static PyObject *__pyx_m; 474 | static PyObject *__pyx_d; 475 | static PyObject *__pyx_b; 476 | static PyObject *__pyx_empty_tuple; 477 | static PyObject *__pyx_empty_bytes; 478 | static PyObject *__pyx_empty_unicode; 479 | static int __pyx_lineno; 480 | static int __pyx_clineno = 0; 481 | static const char * __pyx_cfilenm= __FILE__; 482 | static const char *__pyx_filename; 483 | 484 | 485 | static const char *__pyx_f[] = { 486 | "backpack/_utils/_helpers.pyx", 487 | }; 488 | 489 | /*--- Type declarations ---*/ 490 | struct __pyx_opt_args_8backpack_6_utils_8_helpers__data_get; 491 | 492 | /* "backpack/_utils/_helpers.pyx":26 493 | * 494 | * 495 | * cdef _data_get(target, key, default=None): # <<<<<<<<<<<<<< 496 | * if key is None: 497 | * return target 498 | */ 499 | struct __pyx_opt_args_8backpack_6_utils_8_helpers__data_get { 500 | int __pyx_n; 501 | PyObject *__pyx_default; 502 | }; 503 | 504 | /* --- Runtime support code (head) --- */ 505 | /* Refnanny.proto */ 506 | #ifndef CYTHON_REFNANNY 507 | #define CYTHON_REFNANNY 0 508 | #endif 509 | #if CYTHON_REFNANNY 510 | typedef struct { 511 | void (*INCREF)(void*, PyObject*, int); 512 | void (*DECREF)(void*, PyObject*, int); 513 | void (*GOTREF)(void*, PyObject*, int); 514 | void (*GIVEREF)(void*, PyObject*, int); 515 | void* (*SetupContext)(const char*, int, const char*); 516 | void (*FinishContext)(void**); 517 | } __Pyx_RefNannyAPIStruct; 518 | static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; 519 | static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); 520 | #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; 521 | #ifdef WITH_THREAD 522 | #define __Pyx_RefNannySetupContext(name, acquire_gil)\ 523 | if (acquire_gil) {\ 524 | PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ 525 | __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ 526 | PyGILState_Release(__pyx_gilstate_save);\ 527 | } else {\ 528 | __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__);\ 529 | } 530 | #else 531 | #define __Pyx_RefNannySetupContext(name, acquire_gil)\ 532 | __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__) 533 | #endif 534 | #define __Pyx_RefNannyFinishContext()\ 535 | __Pyx_RefNanny->FinishContext(&__pyx_refnanny) 536 | #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__) 537 | #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__) 538 | #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__) 539 | #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__) 540 | #define __Pyx_XINCREF(r) do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0) 541 | #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0) 542 | #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0) 543 | #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0) 544 | #else 545 | #define __Pyx_RefNannyDeclarations 546 | #define __Pyx_RefNannySetupContext(name, acquire_gil) 547 | #define __Pyx_RefNannyFinishContext() 548 | #define __Pyx_INCREF(r) Py_INCREF(r) 549 | #define __Pyx_DECREF(r) Py_DECREF(r) 550 | #define __Pyx_GOTREF(r) 551 | #define __Pyx_GIVEREF(r) 552 | #define __Pyx_XINCREF(r) Py_XINCREF(r) 553 | #define __Pyx_XDECREF(r) Py_XDECREF(r) 554 | #define __Pyx_XGOTREF(r) 555 | #define __Pyx_XGIVEREF(r) 556 | #endif 557 | #define __Pyx_XDECREF_SET(r, v) do {\ 558 | PyObject *tmp = (PyObject *) r;\ 559 | r = v; __Pyx_XDECREF(tmp);\ 560 | } while (0) 561 | #define __Pyx_DECREF_SET(r, v) do {\ 562 | PyObject *tmp = (PyObject *) r;\ 563 | r = v; __Pyx_DECREF(tmp);\ 564 | } while (0) 565 | #define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) 566 | #define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) 567 | 568 | /* PyObjectGetAttrStr.proto */ 569 | #if CYTHON_COMPILING_IN_CPYTHON 570 | static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { 571 | PyTypeObject* tp = Py_TYPE(obj); 572 | if (likely(tp->tp_getattro)) 573 | return tp->tp_getattro(obj, attr_name); 574 | #if PY_MAJOR_VERSION < 3 575 | if (likely(tp->tp_getattr)) 576 | return tp->tp_getattr(obj, PyString_AS_STRING(attr_name)); 577 | #endif 578 | return PyObject_GetAttr(obj, attr_name); 579 | } 580 | #else 581 | #define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) 582 | #endif 583 | 584 | /* GetBuiltinName.proto */ 585 | static PyObject *__Pyx_GetBuiltinName(PyObject *name); 586 | 587 | /* CallableCheck.proto */ 588 | #if CYTHON_COMPILING_IN_CPYTHON && PY_MAJOR_VERSION >= 3 589 | #define __Pyx_PyCallable_Check(obj) ((obj)->ob_type->tp_call != NULL) 590 | #else 591 | #define __Pyx_PyCallable_Check(obj) PyCallable_Check(obj) 592 | #endif 593 | 594 | /* PyObjectCall.proto */ 595 | #if CYTHON_COMPILING_IN_CPYTHON 596 | static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); 597 | #else 598 | #define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) 599 | #endif 600 | 601 | /* PyObjectCallMethO.proto */ 602 | #if CYTHON_COMPILING_IN_CPYTHON 603 | static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); 604 | #endif 605 | 606 | /* PyObjectCallOneArg.proto */ 607 | static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); 608 | 609 | /* PyObjectCallNoArg.proto */ 610 | #if CYTHON_COMPILING_IN_CPYTHON 611 | static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); 612 | #else 613 | #define __Pyx_PyObject_CallNoArg(func) __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL) 614 | #endif 615 | 616 | /* RaiseArgTupleInvalid.proto */ 617 | static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, 618 | Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); 619 | 620 | /* RaiseDoubleKeywords.proto */ 621 | static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); 622 | 623 | /* ParseKeywords.proto */ 624 | static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],\ 625 | PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,\ 626 | const char* function_name); 627 | 628 | /* PyThreadStateGet.proto */ 629 | #if CYTHON_COMPILING_IN_CPYTHON 630 | #define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; 631 | #define __Pyx_PyThreadState_assign __pyx_tstate = PyThreadState_GET(); 632 | #else 633 | #define __Pyx_PyThreadState_declare 634 | #define __Pyx_PyThreadState_assign 635 | #endif 636 | 637 | /* SaveResetException.proto */ 638 | #if CYTHON_COMPILING_IN_CPYTHON 639 | #define __Pyx_ExceptionSave(type, value, tb) __Pyx__ExceptionSave(__pyx_tstate, type, value, tb) 640 | static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); 641 | #define __Pyx_ExceptionReset(type, value, tb) __Pyx__ExceptionReset(__pyx_tstate, type, value, tb) 642 | static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); 643 | #else 644 | #define __Pyx_ExceptionSave(type, value, tb) PyErr_GetExcInfo(type, value, tb) 645 | #define __Pyx_ExceptionReset(type, value, tb) PyErr_SetExcInfo(type, value, tb) 646 | #endif 647 | 648 | /* PyErrExceptionMatches.proto */ 649 | #if CYTHON_COMPILING_IN_CPYTHON 650 | #define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) 651 | static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); 652 | #else 653 | #define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) 654 | #endif 655 | 656 | /* GetException.proto */ 657 | #if CYTHON_COMPILING_IN_CPYTHON 658 | #define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) 659 | static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); 660 | #else 661 | static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); 662 | #endif 663 | 664 | /* GetModuleGlobalName.proto */ 665 | static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); 666 | 667 | /* GetAttr.proto */ 668 | static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *, PyObject *); 669 | 670 | /* CodeObjectCache.proto */ 671 | typedef struct { 672 | PyCodeObject* code_object; 673 | int code_line; 674 | } __Pyx_CodeObjectCacheEntry; 675 | struct __Pyx_CodeObjectCache { 676 | int count; 677 | int max_count; 678 | __Pyx_CodeObjectCacheEntry* entries; 679 | }; 680 | static struct __Pyx_CodeObjectCache __pyx_code_cache = {0,0,NULL}; 681 | static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); 682 | static PyCodeObject *__pyx_find_code_object(int code_line); 683 | static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object); 684 | 685 | /* AddTraceback.proto */ 686 | static void __Pyx_AddTraceback(const char *funcname, int c_line, 687 | int py_line, const char *filename); 688 | 689 | /* CIntToPy.proto */ 690 | static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value); 691 | 692 | /* CIntFromPy.proto */ 693 | static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *); 694 | 695 | /* CIntFromPy.proto */ 696 | static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *); 697 | 698 | /* CheckBinaryVersion.proto */ 699 | static int __Pyx_check_binary_version(void); 700 | 701 | /* InitStrings.proto */ 702 | static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); 703 | 704 | 705 | /* Module declarations from 'backpack._utils._helpers' */ 706 | static PyObject *__pyx_f_8backpack_6_utils_8_helpers__data_get(PyObject *, PyObject *, struct __pyx_opt_args_8backpack_6_utils_8_helpers__data_get *__pyx_optional_args); /*proto*/ 707 | #define __Pyx_MODULE_NAME "backpack._utils._helpers" 708 | int __pyx_module_is_main_backpack___utils___helpers = 0; 709 | 710 | /* Implementation of 'backpack._utils._helpers' */ 711 | static PyObject *__pyx_builtin_IndexError; 712 | static PyObject *__pyx_builtin_KeyError; 713 | static PyObject *__pyx_builtin_TypeError; 714 | static PyObject *__pyx_builtin_AttributeError; 715 | static const char __pyx_k_[] = "."; 716 | static const char __pyx_k_key[] = "key"; 717 | static const char __pyx_k_val[] = "val"; 718 | static const char __pyx_k_main[] = "__main__"; 719 | static const char __pyx_k_test[] = "__test__"; 720 | static const char __pyx_k_split[] = "split"; 721 | static const char __pyx_k_value[] = "value"; 722 | static const char __pyx_k_target[] = "target"; 723 | static const char __pyx_k_default[] = "default"; 724 | static const char __pyx_k_KeyError[] = "KeyError"; 725 | static const char __pyx_k_data_get[] = "data_get"; 726 | static const char __pyx_k_TypeError[] = "TypeError"; 727 | static const char __pyx_k_IndexError[] = "IndexError"; 728 | static const char __pyx_k_AttributeError[] = "AttributeError"; 729 | static const char __pyx_k_backpack__utils__helpers[] = "backpack._utils._helpers"; 730 | static const char __pyx_k_Users_sebastien_src_sdispater_b[] = "/Users/sebastien/src/sdispater/backpack/backpack/_utils/_helpers.pyx"; 731 | static PyObject *__pyx_kp_s_; 732 | static PyObject *__pyx_n_s_AttributeError; 733 | static PyObject *__pyx_n_s_IndexError; 734 | static PyObject *__pyx_n_s_KeyError; 735 | static PyObject *__pyx_n_s_TypeError; 736 | static PyObject *__pyx_kp_s_Users_sebastien_src_sdispater_b; 737 | static PyObject *__pyx_n_s_backpack__utils__helpers; 738 | static PyObject *__pyx_n_s_data_get; 739 | static PyObject *__pyx_n_s_default; 740 | static PyObject *__pyx_n_s_key; 741 | static PyObject *__pyx_n_s_main; 742 | static PyObject *__pyx_n_s_split; 743 | static PyObject *__pyx_n_s_target; 744 | static PyObject *__pyx_n_s_test; 745 | static PyObject *__pyx_n_s_val; 746 | static PyObject *__pyx_n_s_value; 747 | static PyObject *__pyx_pf_8backpack_6_utils_8_helpers_value(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_val); /* proto */ 748 | static PyObject *__pyx_pf_8backpack_6_utils_8_helpers_2data_get(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_target, PyObject *__pyx_v_key, PyObject *__pyx_v_default); /* proto */ 749 | static PyObject *__pyx_tuple__2; 750 | static PyObject *__pyx_tuple__3; 751 | static PyObject *__pyx_tuple__5; 752 | static PyObject *__pyx_codeobj__4; 753 | static PyObject *__pyx_codeobj__6; 754 | 755 | /* "backpack/_utils/_helpers.pyx":1 756 | * def value(val): # <<<<<<<<<<<<<< 757 | * if callable(val): 758 | * return val() 759 | */ 760 | 761 | /* Python wrapper */ 762 | static PyObject *__pyx_pw_8backpack_6_utils_8_helpers_1value(PyObject *__pyx_self, PyObject *__pyx_v_val); /*proto*/ 763 | static PyMethodDef __pyx_mdef_8backpack_6_utils_8_helpers_1value = {"value", (PyCFunction)__pyx_pw_8backpack_6_utils_8_helpers_1value, METH_O, 0}; 764 | static PyObject *__pyx_pw_8backpack_6_utils_8_helpers_1value(PyObject *__pyx_self, PyObject *__pyx_v_val) { 765 | PyObject *__pyx_r = 0; 766 | __Pyx_RefNannyDeclarations 767 | __Pyx_RefNannySetupContext("value (wrapper)", 0); 768 | __pyx_r = __pyx_pf_8backpack_6_utils_8_helpers_value(__pyx_self, ((PyObject *)__pyx_v_val)); 769 | 770 | /* function exit code */ 771 | __Pyx_RefNannyFinishContext(); 772 | return __pyx_r; 773 | } 774 | 775 | static PyObject *__pyx_pf_8backpack_6_utils_8_helpers_value(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_val) { 776 | PyObject *__pyx_r = NULL; 777 | __Pyx_RefNannyDeclarations 778 | int __pyx_t_1; 779 | int __pyx_t_2; 780 | PyObject *__pyx_t_3 = NULL; 781 | PyObject *__pyx_t_4 = NULL; 782 | PyObject *__pyx_t_5 = NULL; 783 | __Pyx_RefNannySetupContext("value", 0); 784 | 785 | /* "backpack/_utils/_helpers.pyx":2 786 | * def value(val): 787 | * if callable(val): # <<<<<<<<<<<<<< 788 | * return val() 789 | * 790 | */ 791 | __pyx_t_1 = __Pyx_PyCallable_Check(__pyx_v_val); if (unlikely(__pyx_t_1 == -1)) __PYX_ERR(0, 2, __pyx_L1_error) 792 | __pyx_t_2 = (__pyx_t_1 != 0); 793 | if (__pyx_t_2) { 794 | 795 | /* "backpack/_utils/_helpers.pyx":3 796 | * def value(val): 797 | * if callable(val): 798 | * return val() # <<<<<<<<<<<<<< 799 | * 800 | * return val 801 | */ 802 | __Pyx_XDECREF(__pyx_r); 803 | __Pyx_INCREF(__pyx_v_val); 804 | __pyx_t_4 = __pyx_v_val; __pyx_t_5 = NULL; 805 | if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_4))) { 806 | __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_4); 807 | if (likely(__pyx_t_5)) { 808 | PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4); 809 | __Pyx_INCREF(__pyx_t_5); 810 | __Pyx_INCREF(function); 811 | __Pyx_DECREF_SET(__pyx_t_4, function); 812 | } 813 | } 814 | if (__pyx_t_5) { 815 | __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3, __pyx_L1_error) 816 | __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; 817 | } else { 818 | __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 3, __pyx_L1_error) 819 | } 820 | __Pyx_GOTREF(__pyx_t_3); 821 | __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; 822 | __pyx_r = __pyx_t_3; 823 | __pyx_t_3 = 0; 824 | goto __pyx_L0; 825 | 826 | /* "backpack/_utils/_helpers.pyx":2 827 | * def value(val): 828 | * if callable(val): # <<<<<<<<<<<<<< 829 | * return val() 830 | * 831 | */ 832 | } 833 | 834 | /* "backpack/_utils/_helpers.pyx":5 835 | * return val() 836 | * 837 | * return val # <<<<<<<<<<<<<< 838 | * 839 | * 840 | */ 841 | __Pyx_XDECREF(__pyx_r); 842 | __Pyx_INCREF(__pyx_v_val); 843 | __pyx_r = __pyx_v_val; 844 | goto __pyx_L0; 845 | 846 | /* "backpack/_utils/_helpers.pyx":1 847 | * def value(val): # <<<<<<<<<<<<<< 848 | * if callable(val): 849 | * return val() 850 | */ 851 | 852 | /* function exit code */ 853 | __pyx_L1_error:; 854 | __Pyx_XDECREF(__pyx_t_3); 855 | __Pyx_XDECREF(__pyx_t_4); 856 | __Pyx_XDECREF(__pyx_t_5); 857 | __Pyx_AddTraceback("backpack._utils._helpers.value", __pyx_clineno, __pyx_lineno, __pyx_filename); 858 | __pyx_r = NULL; 859 | __pyx_L0:; 860 | __Pyx_XGIVEREF(__pyx_r); 861 | __Pyx_RefNannyFinishContext(); 862 | return __pyx_r; 863 | } 864 | 865 | /* "backpack/_utils/_helpers.pyx":8 866 | * 867 | * 868 | * def data_get(target, key, default=None): # <<<<<<<<<<<<<< 869 | * """ 870 | * Get an item from a list, a dict or an object using "dot" notation. 871 | */ 872 | 873 | /* Python wrapper */ 874 | static PyObject *__pyx_pw_8backpack_6_utils_8_helpers_3data_get(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ 875 | static char __pyx_doc_8backpack_6_utils_8_helpers_2data_get[] = "\n Get an item from a list, a dict or an object using \"dot\" notation.\n\n :param target: The target element\n :type target: list or dict or object\n\n :param key: The key to get\n :type key: string or list\n\n :param default: The default value\n :type default: mixed\n\n :rtype: mixed\n "; 876 | static PyMethodDef __pyx_mdef_8backpack_6_utils_8_helpers_3data_get = {"data_get", (PyCFunction)__pyx_pw_8backpack_6_utils_8_helpers_3data_get, METH_VARARGS|METH_KEYWORDS, __pyx_doc_8backpack_6_utils_8_helpers_2data_get}; 877 | static PyObject *__pyx_pw_8backpack_6_utils_8_helpers_3data_get(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { 878 | PyObject *__pyx_v_target = 0; 879 | PyObject *__pyx_v_key = 0; 880 | PyObject *__pyx_v_default = 0; 881 | PyObject *__pyx_r = 0; 882 | __Pyx_RefNannyDeclarations 883 | __Pyx_RefNannySetupContext("data_get (wrapper)", 0); 884 | { 885 | static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_target,&__pyx_n_s_key,&__pyx_n_s_default,0}; 886 | PyObject* values[3] = {0,0,0}; 887 | values[2] = ((PyObject *)Py_None); 888 | if (unlikely(__pyx_kwds)) { 889 | Py_ssize_t kw_args; 890 | const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args); 891 | switch (pos_args) { 892 | case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); 893 | case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); 894 | case 1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0); 895 | case 0: break; 896 | default: goto __pyx_L5_argtuple_error; 897 | } 898 | kw_args = PyDict_Size(__pyx_kwds); 899 | switch (pos_args) { 900 | case 0: 901 | if (likely((values[0] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_target)) != 0)) kw_args--; 902 | else goto __pyx_L5_argtuple_error; 903 | case 1: 904 | if (likely((values[1] = PyDict_GetItem(__pyx_kwds, __pyx_n_s_key)) != 0)) kw_args--; 905 | else { 906 | __Pyx_RaiseArgtupleInvalid("data_get", 0, 2, 3, 1); __PYX_ERR(0, 8, __pyx_L3_error) 907 | } 908 | case 2: 909 | if (kw_args > 0) { 910 | PyObject* value = PyDict_GetItem(__pyx_kwds, __pyx_n_s_default); 911 | if (value) { values[2] = value; kw_args--; } 912 | } 913 | } 914 | if (unlikely(kw_args > 0)) { 915 | if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "data_get") < 0)) __PYX_ERR(0, 8, __pyx_L3_error) 916 | } 917 | } else { 918 | switch (PyTuple_GET_SIZE(__pyx_args)) { 919 | case 3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2); 920 | case 2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1); 921 | values[0] = PyTuple_GET_ITEM(__pyx_args, 0); 922 | break; 923 | default: goto __pyx_L5_argtuple_error; 924 | } 925 | } 926 | __pyx_v_target = values[0]; 927 | __pyx_v_key = values[1]; 928 | __pyx_v_default = values[2]; 929 | } 930 | goto __pyx_L4_argument_unpacking_done; 931 | __pyx_L5_argtuple_error:; 932 | __Pyx_RaiseArgtupleInvalid("data_get", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 8, __pyx_L3_error) 933 | __pyx_L3_error:; 934 | __Pyx_AddTraceback("backpack._utils._helpers.data_get", __pyx_clineno, __pyx_lineno, __pyx_filename); 935 | __Pyx_RefNannyFinishContext(); 936 | return NULL; 937 | __pyx_L4_argument_unpacking_done:; 938 | __pyx_r = __pyx_pf_8backpack_6_utils_8_helpers_2data_get(__pyx_self, __pyx_v_target, __pyx_v_key, __pyx_v_default); 939 | 940 | /* function exit code */ 941 | __Pyx_RefNannyFinishContext(); 942 | return __pyx_r; 943 | } 944 | 945 | static PyObject *__pyx_pf_8backpack_6_utils_8_helpers_2data_get(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_target, PyObject *__pyx_v_key, PyObject *__pyx_v_default) { 946 | PyObject *__pyx_r = NULL; 947 | __Pyx_RefNannyDeclarations 948 | PyObject *__pyx_t_1 = NULL; 949 | struct __pyx_opt_args_8backpack_6_utils_8_helpers__data_get __pyx_t_2; 950 | __Pyx_RefNannySetupContext("data_get", 0); 951 | 952 | /* "backpack/_utils/_helpers.pyx":23 953 | * :rtype: mixed 954 | * """ 955 | * return _data_get(target, key, default) # <<<<<<<<<<<<<< 956 | * 957 | * 958 | */ 959 | __Pyx_XDECREF(__pyx_r); 960 | __pyx_t_2.__pyx_n = 1; 961 | __pyx_t_2.__pyx_default = __pyx_v_default; 962 | __pyx_t_1 = __pyx_f_8backpack_6_utils_8_helpers__data_get(__pyx_v_target, __pyx_v_key, &__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 23, __pyx_L1_error) 963 | __Pyx_GOTREF(__pyx_t_1); 964 | __pyx_r = __pyx_t_1; 965 | __pyx_t_1 = 0; 966 | goto __pyx_L0; 967 | 968 | /* "backpack/_utils/_helpers.pyx":8 969 | * 970 | * 971 | * def data_get(target, key, default=None): # <<<<<<<<<<<<<< 972 | * """ 973 | * Get an item from a list, a dict or an object using "dot" notation. 974 | */ 975 | 976 | /* function exit code */ 977 | __pyx_L1_error:; 978 | __Pyx_XDECREF(__pyx_t_1); 979 | __Pyx_AddTraceback("backpack._utils._helpers.data_get", __pyx_clineno, __pyx_lineno, __pyx_filename); 980 | __pyx_r = NULL; 981 | __pyx_L0:; 982 | __Pyx_XGIVEREF(__pyx_r); 983 | __Pyx_RefNannyFinishContext(); 984 | return __pyx_r; 985 | } 986 | 987 | /* "backpack/_utils/_helpers.pyx":26 988 | * 989 | * 990 | * cdef _data_get(target, key, default=None): # <<<<<<<<<<<<<< 991 | * if key is None: 992 | * return target 993 | */ 994 | 995 | static PyObject *__pyx_f_8backpack_6_utils_8_helpers__data_get(PyObject *__pyx_v_target, PyObject *__pyx_v_key, struct __pyx_opt_args_8backpack_6_utils_8_helpers__data_get *__pyx_optional_args) { 996 | PyObject *__pyx_v_default = ((PyObject *)Py_None); 997 | PyObject *__pyx_v_segment = NULL; 998 | PyObject *__pyx_r = NULL; 999 | __Pyx_RefNannyDeclarations 1000 | int __pyx_t_1; 1001 | int __pyx_t_2; 1002 | PyObject *__pyx_t_3 = NULL; 1003 | PyObject *__pyx_t_4 = NULL; 1004 | Py_ssize_t __pyx_t_5; 1005 | PyObject *(*__pyx_t_6)(PyObject *); 1006 | int __pyx_t_7; 1007 | PyObject *__pyx_t_8 = NULL; 1008 | PyObject *__pyx_t_9 = NULL; 1009 | PyObject *__pyx_t_10 = NULL; 1010 | int __pyx_t_11; 1011 | PyObject *__pyx_t_12 = NULL; 1012 | PyObject *__pyx_t_13 = NULL; 1013 | PyObject *__pyx_t_14 = NULL; 1014 | PyObject *__pyx_t_15 = NULL; 1015 | PyObject *__pyx_t_16 = NULL; 1016 | PyObject *__pyx_t_17 = NULL; 1017 | PyObject *__pyx_t_18 = NULL; 1018 | PyObject *__pyx_t_19 = NULL; 1019 | PyObject *__pyx_t_20 = NULL; 1020 | PyObject *__pyx_t_21 = NULL; 1021 | PyObject *__pyx_t_22 = NULL; 1022 | PyObject *__pyx_t_23 = NULL; 1023 | __Pyx_RefNannySetupContext("_data_get", 0); 1024 | if (__pyx_optional_args) { 1025 | if (__pyx_optional_args->__pyx_n > 0) { 1026 | __pyx_v_default = __pyx_optional_args->__pyx_default; 1027 | } 1028 | } 1029 | __Pyx_INCREF(__pyx_v_target); 1030 | __Pyx_INCREF(__pyx_v_key); 1031 | 1032 | /* "backpack/_utils/_helpers.pyx":27 1033 | * 1034 | * cdef _data_get(target, key, default=None): 1035 | * if key is None: # <<<<<<<<<<<<<< 1036 | * return target 1037 | * 1038 | */ 1039 | __pyx_t_1 = (__pyx_v_key == Py_None); 1040 | __pyx_t_2 = (__pyx_t_1 != 0); 1041 | if (__pyx_t_2) { 1042 | 1043 | /* "backpack/_utils/_helpers.pyx":28 1044 | * cdef _data_get(target, key, default=None): 1045 | * if key is None: 1046 | * return target # <<<<<<<<<<<<<< 1047 | * 1048 | * if not isinstance(key, list): 1049 | */ 1050 | __Pyx_XDECREF(__pyx_r); 1051 | __Pyx_INCREF(__pyx_v_target); 1052 | __pyx_r = __pyx_v_target; 1053 | goto __pyx_L0; 1054 | 1055 | /* "backpack/_utils/_helpers.pyx":27 1056 | * 1057 | * cdef _data_get(target, key, default=None): 1058 | * if key is None: # <<<<<<<<<<<<<< 1059 | * return target 1060 | * 1061 | */ 1062 | } 1063 | 1064 | /* "backpack/_utils/_helpers.pyx":30 1065 | * return target 1066 | * 1067 | * if not isinstance(key, list): # <<<<<<<<<<<<<< 1068 | * key = key.split('.') 1069 | * 1070 | */ 1071 | __pyx_t_2 = PyList_Check(__pyx_v_key); 1072 | __pyx_t_1 = ((!(__pyx_t_2 != 0)) != 0); 1073 | if (__pyx_t_1) { 1074 | 1075 | /* "backpack/_utils/_helpers.pyx":31 1076 | * 1077 | * if not isinstance(key, list): 1078 | * key = key.split('.') # <<<<<<<<<<<<<< 1079 | * 1080 | * for segment in key: 1081 | */ 1082 | __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_key, __pyx_n_s_split); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 31, __pyx_L1_error) 1083 | __Pyx_GOTREF(__pyx_t_3); 1084 | __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 31, __pyx_L1_error) 1085 | __Pyx_GOTREF(__pyx_t_4); 1086 | __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; 1087 | __Pyx_DECREF_SET(__pyx_v_key, __pyx_t_4); 1088 | __pyx_t_4 = 0; 1089 | 1090 | /* "backpack/_utils/_helpers.pyx":30 1091 | * return target 1092 | * 1093 | * if not isinstance(key, list): # <<<<<<<<<<<<<< 1094 | * key = key.split('.') 1095 | * 1096 | */ 1097 | } 1098 | 1099 | /* "backpack/_utils/_helpers.pyx":33 1100 | * key = key.split('.') 1101 | * 1102 | * for segment in key: # <<<<<<<<<<<<<< 1103 | * if isinstance(target, (list, tuple)): 1104 | * try: 1105 | */ 1106 | if (likely(PyList_CheckExact(__pyx_v_key)) || PyTuple_CheckExact(__pyx_v_key)) { 1107 | __pyx_t_4 = __pyx_v_key; __Pyx_INCREF(__pyx_t_4); __pyx_t_5 = 0; 1108 | __pyx_t_6 = NULL; 1109 | } else { 1110 | __pyx_t_5 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_v_key); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 33, __pyx_L1_error) 1111 | __Pyx_GOTREF(__pyx_t_4); 1112 | __pyx_t_6 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 33, __pyx_L1_error) 1113 | } 1114 | for (;;) { 1115 | if (likely(!__pyx_t_6)) { 1116 | if (likely(PyList_CheckExact(__pyx_t_4))) { 1117 | if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_4)) break; 1118 | #if CYTHON_COMPILING_IN_CPYTHON 1119 | __pyx_t_3 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(0, 33, __pyx_L1_error) 1120 | #else 1121 | __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) 1122 | __Pyx_GOTREF(__pyx_t_3); 1123 | #endif 1124 | } else { 1125 | if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_4)) break; 1126 | #if CYTHON_COMPILING_IN_CPYTHON 1127 | __pyx_t_3 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_5); __Pyx_INCREF(__pyx_t_3); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(0, 33, __pyx_L1_error) 1128 | #else 1129 | __pyx_t_3 = PySequence_ITEM(__pyx_t_4, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) 1130 | __Pyx_GOTREF(__pyx_t_3); 1131 | #endif 1132 | } 1133 | } else { 1134 | __pyx_t_3 = __pyx_t_6(__pyx_t_4); 1135 | if (unlikely(!__pyx_t_3)) { 1136 | PyObject* exc_type = PyErr_Occurred(); 1137 | if (exc_type) { 1138 | if (likely(exc_type == PyExc_StopIteration || PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear(); 1139 | else __PYX_ERR(0, 33, __pyx_L1_error) 1140 | } 1141 | break; 1142 | } 1143 | __Pyx_GOTREF(__pyx_t_3); 1144 | } 1145 | __Pyx_XDECREF_SET(__pyx_v_segment, __pyx_t_3); 1146 | __pyx_t_3 = 0; 1147 | 1148 | /* "backpack/_utils/_helpers.pyx":34 1149 | * 1150 | * for segment in key: 1151 | * if isinstance(target, (list, tuple)): # <<<<<<<<<<<<<< 1152 | * try: 1153 | * target = target[segment] 1154 | */ 1155 | __pyx_t_2 = PyList_Check(__pyx_v_target); 1156 | __pyx_t_7 = (__pyx_t_2 != 0); 1157 | if (!__pyx_t_7) { 1158 | } else { 1159 | __pyx_t_1 = __pyx_t_7; 1160 | goto __pyx_L8_bool_binop_done; 1161 | } 1162 | __pyx_t_7 = PyTuple_Check(__pyx_v_target); 1163 | __pyx_t_2 = (__pyx_t_7 != 0); 1164 | __pyx_t_1 = __pyx_t_2; 1165 | __pyx_L8_bool_binop_done:; 1166 | __pyx_t_2 = (__pyx_t_1 != 0); 1167 | if (__pyx_t_2) { 1168 | 1169 | /* "backpack/_utils/_helpers.pyx":35 1170 | * for segment in key: 1171 | * if isinstance(target, (list, tuple)): 1172 | * try: # <<<<<<<<<<<<<< 1173 | * target = target[segment] 1174 | * except IndexError: 1175 | */ 1176 | { 1177 | __Pyx_PyThreadState_declare 1178 | __Pyx_PyThreadState_assign 1179 | __Pyx_ExceptionSave(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10); 1180 | __Pyx_XGOTREF(__pyx_t_8); 1181 | __Pyx_XGOTREF(__pyx_t_9); 1182 | __Pyx_XGOTREF(__pyx_t_10); 1183 | /*try:*/ { 1184 | 1185 | /* "backpack/_utils/_helpers.pyx":36 1186 | * if isinstance(target, (list, tuple)): 1187 | * try: 1188 | * target = target[segment] # <<<<<<<<<<<<<< 1189 | * except IndexError: 1190 | * return value(default) 1191 | */ 1192 | __pyx_t_3 = PyObject_GetItem(__pyx_v_target, __pyx_v_segment); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 36, __pyx_L10_error) 1193 | __Pyx_GOTREF(__pyx_t_3); 1194 | __Pyx_DECREF_SET(__pyx_v_target, __pyx_t_3); 1195 | __pyx_t_3 = 0; 1196 | 1197 | /* "backpack/_utils/_helpers.pyx":35 1198 | * for segment in key: 1199 | * if isinstance(target, (list, tuple)): 1200 | * try: # <<<<<<<<<<<<<< 1201 | * target = target[segment] 1202 | * except IndexError: 1203 | */ 1204 | } 1205 | __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; 1206 | __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; 1207 | __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; 1208 | goto __pyx_L17_try_end; 1209 | __pyx_L10_error:; 1210 | __Pyx_PyThreadState_assign 1211 | __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; 1212 | 1213 | /* "backpack/_utils/_helpers.pyx":37 1214 | * try: 1215 | * target = target[segment] 1216 | * except IndexError: # <<<<<<<<<<<<<< 1217 | * return value(default) 1218 | * elif isinstance(target, dict): 1219 | */ 1220 | __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_IndexError); 1221 | if (__pyx_t_11) { 1222 | __Pyx_AddTraceback("backpack._utils._helpers._data_get", __pyx_clineno, __pyx_lineno, __pyx_filename); 1223 | if (__Pyx_GetException(&__pyx_t_3, &__pyx_t_12, &__pyx_t_13) < 0) __PYX_ERR(0, 37, __pyx_L12_except_error) 1224 | __Pyx_GOTREF(__pyx_t_3); 1225 | __Pyx_GOTREF(__pyx_t_12); 1226 | __Pyx_GOTREF(__pyx_t_13); 1227 | 1228 | /* "backpack/_utils/_helpers.pyx":38 1229 | * target = target[segment] 1230 | * except IndexError: 1231 | * return value(default) # <<<<<<<<<<<<<< 1232 | * elif isinstance(target, dict): 1233 | * try: 1234 | */ 1235 | __Pyx_XDECREF(__pyx_r); 1236 | __pyx_t_15 = __Pyx_GetModuleGlobalName(__pyx_n_s_value); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 38, __pyx_L12_except_error) 1237 | __Pyx_GOTREF(__pyx_t_15); 1238 | __pyx_t_16 = NULL; 1239 | if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_15))) { 1240 | __pyx_t_16 = PyMethod_GET_SELF(__pyx_t_15); 1241 | if (likely(__pyx_t_16)) { 1242 | PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_15); 1243 | __Pyx_INCREF(__pyx_t_16); 1244 | __Pyx_INCREF(function); 1245 | __Pyx_DECREF_SET(__pyx_t_15, function); 1246 | } 1247 | } 1248 | if (!__pyx_t_16) { 1249 | __pyx_t_14 = __Pyx_PyObject_CallOneArg(__pyx_t_15, __pyx_v_default); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 38, __pyx_L12_except_error) 1250 | __Pyx_GOTREF(__pyx_t_14); 1251 | } else { 1252 | __pyx_t_17 = PyTuple_New(1+1); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 38, __pyx_L12_except_error) 1253 | __Pyx_GOTREF(__pyx_t_17); 1254 | __Pyx_GIVEREF(__pyx_t_16); PyTuple_SET_ITEM(__pyx_t_17, 0, __pyx_t_16); __pyx_t_16 = NULL; 1255 | __Pyx_INCREF(__pyx_v_default); 1256 | __Pyx_GIVEREF(__pyx_v_default); 1257 | PyTuple_SET_ITEM(__pyx_t_17, 0+1, __pyx_v_default); 1258 | __pyx_t_14 = __Pyx_PyObject_Call(__pyx_t_15, __pyx_t_17, NULL); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 38, __pyx_L12_except_error) 1259 | __Pyx_GOTREF(__pyx_t_14); 1260 | __Pyx_DECREF(__pyx_t_17); __pyx_t_17 = 0; 1261 | } 1262 | __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0; 1263 | __pyx_r = __pyx_t_14; 1264 | __pyx_t_14 = 0; 1265 | __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; 1266 | __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; 1267 | __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; 1268 | __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; 1269 | goto __pyx_L13_except_return; 1270 | } 1271 | goto __pyx_L12_except_error; 1272 | __pyx_L12_except_error:; 1273 | 1274 | /* "backpack/_utils/_helpers.pyx":35 1275 | * for segment in key: 1276 | * if isinstance(target, (list, tuple)): 1277 | * try: # <<<<<<<<<<<<<< 1278 | * target = target[segment] 1279 | * except IndexError: 1280 | */ 1281 | __Pyx_PyThreadState_assign 1282 | __Pyx_XGIVEREF(__pyx_t_8); 1283 | __Pyx_XGIVEREF(__pyx_t_9); 1284 | __Pyx_XGIVEREF(__pyx_t_10); 1285 | __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10); 1286 | goto __pyx_L1_error; 1287 | __pyx_L13_except_return:; 1288 | __Pyx_PyThreadState_assign 1289 | __Pyx_XGIVEREF(__pyx_t_8); 1290 | __Pyx_XGIVEREF(__pyx_t_9); 1291 | __Pyx_XGIVEREF(__pyx_t_10); 1292 | __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10); 1293 | goto __pyx_L0; 1294 | __pyx_L17_try_end:; 1295 | } 1296 | 1297 | /* "backpack/_utils/_helpers.pyx":34 1298 | * 1299 | * for segment in key: 1300 | * if isinstance(target, (list, tuple)): # <<<<<<<<<<<<<< 1301 | * try: 1302 | * target = target[segment] 1303 | */ 1304 | goto __pyx_L7; 1305 | } 1306 | 1307 | /* "backpack/_utils/_helpers.pyx":39 1308 | * except IndexError: 1309 | * return value(default) 1310 | * elif isinstance(target, dict): # <<<<<<<<<<<<<< 1311 | * try: 1312 | * target = target[segment] 1313 | */ 1314 | __pyx_t_2 = PyDict_Check(__pyx_v_target); 1315 | __pyx_t_1 = (__pyx_t_2 != 0); 1316 | if (__pyx_t_1) { 1317 | 1318 | /* "backpack/_utils/_helpers.pyx":40 1319 | * return value(default) 1320 | * elif isinstance(target, dict): 1321 | * try: # <<<<<<<<<<<<<< 1322 | * target = target[segment] 1323 | * except IndexError: 1324 | */ 1325 | { 1326 | __Pyx_PyThreadState_declare 1327 | __Pyx_PyThreadState_assign 1328 | __Pyx_ExceptionSave(&__pyx_t_10, &__pyx_t_9, &__pyx_t_8); 1329 | __Pyx_XGOTREF(__pyx_t_10); 1330 | __Pyx_XGOTREF(__pyx_t_9); 1331 | __Pyx_XGOTREF(__pyx_t_8); 1332 | /*try:*/ { 1333 | 1334 | /* "backpack/_utils/_helpers.pyx":41 1335 | * elif isinstance(target, dict): 1336 | * try: 1337 | * target = target[segment] # <<<<<<<<<<<<<< 1338 | * except IndexError: 1339 | * return value(default) 1340 | */ 1341 | __pyx_t_13 = PyObject_GetItem(__pyx_v_target, __pyx_v_segment); if (unlikely(!__pyx_t_13)) __PYX_ERR(0, 41, __pyx_L20_error) 1342 | __Pyx_GOTREF(__pyx_t_13); 1343 | __Pyx_DECREF_SET(__pyx_v_target, __pyx_t_13); 1344 | __pyx_t_13 = 0; 1345 | 1346 | /* "backpack/_utils/_helpers.pyx":40 1347 | * return value(default) 1348 | * elif isinstance(target, dict): 1349 | * try: # <<<<<<<<<<<<<< 1350 | * target = target[segment] 1351 | * except IndexError: 1352 | */ 1353 | } 1354 | __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; 1355 | __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; 1356 | __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; 1357 | goto __pyx_L27_try_end; 1358 | __pyx_L20_error:; 1359 | __Pyx_PyThreadState_assign 1360 | __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0; 1361 | __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0; 1362 | __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; 1363 | __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; 1364 | __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; 1365 | __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; 1366 | __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; 1367 | 1368 | /* "backpack/_utils/_helpers.pyx":42 1369 | * try: 1370 | * target = target[segment] 1371 | * except IndexError: # <<<<<<<<<<<<<< 1372 | * return value(default) 1373 | * else: 1374 | */ 1375 | __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_IndexError); 1376 | if (__pyx_t_11) { 1377 | __Pyx_AddTraceback("backpack._utils._helpers._data_get", __pyx_clineno, __pyx_lineno, __pyx_filename); 1378 | if (__Pyx_GetException(&__pyx_t_13, &__pyx_t_12, &__pyx_t_3) < 0) __PYX_ERR(0, 42, __pyx_L22_except_error) 1379 | __Pyx_GOTREF(__pyx_t_13); 1380 | __Pyx_GOTREF(__pyx_t_12); 1381 | __Pyx_GOTREF(__pyx_t_3); 1382 | 1383 | /* "backpack/_utils/_helpers.pyx":43 1384 | * target = target[segment] 1385 | * except IndexError: 1386 | * return value(default) # <<<<<<<<<<<<<< 1387 | * else: 1388 | * try: 1389 | */ 1390 | __Pyx_XDECREF(__pyx_r); 1391 | __pyx_t_15 = __Pyx_GetModuleGlobalName(__pyx_n_s_value); if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 43, __pyx_L22_except_error) 1392 | __Pyx_GOTREF(__pyx_t_15); 1393 | __pyx_t_17 = NULL; 1394 | if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_15))) { 1395 | __pyx_t_17 = PyMethod_GET_SELF(__pyx_t_15); 1396 | if (likely(__pyx_t_17)) { 1397 | PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_15); 1398 | __Pyx_INCREF(__pyx_t_17); 1399 | __Pyx_INCREF(function); 1400 | __Pyx_DECREF_SET(__pyx_t_15, function); 1401 | } 1402 | } 1403 | if (!__pyx_t_17) { 1404 | __pyx_t_14 = __Pyx_PyObject_CallOneArg(__pyx_t_15, __pyx_v_default); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 43, __pyx_L22_except_error) 1405 | __Pyx_GOTREF(__pyx_t_14); 1406 | } else { 1407 | __pyx_t_16 = PyTuple_New(1+1); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 43, __pyx_L22_except_error) 1408 | __Pyx_GOTREF(__pyx_t_16); 1409 | __Pyx_GIVEREF(__pyx_t_17); PyTuple_SET_ITEM(__pyx_t_16, 0, __pyx_t_17); __pyx_t_17 = NULL; 1410 | __Pyx_INCREF(__pyx_v_default); 1411 | __Pyx_GIVEREF(__pyx_v_default); 1412 | PyTuple_SET_ITEM(__pyx_t_16, 0+1, __pyx_v_default); 1413 | __pyx_t_14 = __Pyx_PyObject_Call(__pyx_t_15, __pyx_t_16, NULL); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 43, __pyx_L22_except_error) 1414 | __Pyx_GOTREF(__pyx_t_14); 1415 | __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0; 1416 | } 1417 | __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0; 1418 | __pyx_r = __pyx_t_14; 1419 | __pyx_t_14 = 0; 1420 | __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; 1421 | __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; 1422 | __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; 1423 | __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; 1424 | goto __pyx_L23_except_return; 1425 | } 1426 | goto __pyx_L22_except_error; 1427 | __pyx_L22_except_error:; 1428 | 1429 | /* "backpack/_utils/_helpers.pyx":40 1430 | * return value(default) 1431 | * elif isinstance(target, dict): 1432 | * try: # <<<<<<<<<<<<<< 1433 | * target = target[segment] 1434 | * except IndexError: 1435 | */ 1436 | __Pyx_PyThreadState_assign 1437 | __Pyx_XGIVEREF(__pyx_t_10); 1438 | __Pyx_XGIVEREF(__pyx_t_9); 1439 | __Pyx_XGIVEREF(__pyx_t_8); 1440 | __Pyx_ExceptionReset(__pyx_t_10, __pyx_t_9, __pyx_t_8); 1441 | goto __pyx_L1_error; 1442 | __pyx_L23_except_return:; 1443 | __Pyx_PyThreadState_assign 1444 | __Pyx_XGIVEREF(__pyx_t_10); 1445 | __Pyx_XGIVEREF(__pyx_t_9); 1446 | __Pyx_XGIVEREF(__pyx_t_8); 1447 | __Pyx_ExceptionReset(__pyx_t_10, __pyx_t_9, __pyx_t_8); 1448 | goto __pyx_L0; 1449 | __pyx_L27_try_end:; 1450 | } 1451 | 1452 | /* "backpack/_utils/_helpers.pyx":39 1453 | * except IndexError: 1454 | * return value(default) 1455 | * elif isinstance(target, dict): # <<<<<<<<<<<<<< 1456 | * try: 1457 | * target = target[segment] 1458 | */ 1459 | goto __pyx_L7; 1460 | } 1461 | 1462 | /* "backpack/_utils/_helpers.pyx":45 1463 | * return value(default) 1464 | * else: 1465 | * try: # <<<<<<<<<<<<<< 1466 | * target = target[segment] 1467 | * except (IndexError, KeyError, TypeError): 1468 | */ 1469 | /*else*/ { 1470 | { 1471 | __Pyx_PyThreadState_declare 1472 | __Pyx_PyThreadState_assign 1473 | __Pyx_ExceptionSave(&__pyx_t_8, &__pyx_t_9, &__pyx_t_10); 1474 | __Pyx_XGOTREF(__pyx_t_8); 1475 | __Pyx_XGOTREF(__pyx_t_9); 1476 | __Pyx_XGOTREF(__pyx_t_10); 1477 | /*try:*/ { 1478 | 1479 | /* "backpack/_utils/_helpers.pyx":46 1480 | * else: 1481 | * try: 1482 | * target = target[segment] # <<<<<<<<<<<<<< 1483 | * except (IndexError, KeyError, TypeError): 1484 | * try: 1485 | */ 1486 | __pyx_t_3 = PyObject_GetItem(__pyx_v_target, __pyx_v_segment); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 46, __pyx_L30_error) 1487 | __Pyx_GOTREF(__pyx_t_3); 1488 | __Pyx_DECREF_SET(__pyx_v_target, __pyx_t_3); 1489 | __pyx_t_3 = 0; 1490 | 1491 | /* "backpack/_utils/_helpers.pyx":45 1492 | * return value(default) 1493 | * else: 1494 | * try: # <<<<<<<<<<<<<< 1495 | * target = target[segment] 1496 | * except (IndexError, KeyError, TypeError): 1497 | */ 1498 | } 1499 | __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; 1500 | __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; 1501 | __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0; 1502 | goto __pyx_L37_try_end; 1503 | __pyx_L30_error:; 1504 | __Pyx_PyThreadState_assign 1505 | __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0; 1506 | __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0; 1507 | __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; 1508 | __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; 1509 | __Pyx_XDECREF(__pyx_t_13); __pyx_t_13 = 0; 1510 | __Pyx_XDECREF(__pyx_t_12); __pyx_t_12 = 0; 1511 | __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; 1512 | 1513 | /* "backpack/_utils/_helpers.pyx":47 1514 | * try: 1515 | * target = target[segment] 1516 | * except (IndexError, KeyError, TypeError): # <<<<<<<<<<<<<< 1517 | * try: 1518 | * target = getattr(target, segment) 1519 | */ 1520 | __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_IndexError) || __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError) || __Pyx_PyErr_ExceptionMatches(__pyx_builtin_TypeError); 1521 | if (__pyx_t_11) { 1522 | __Pyx_AddTraceback("backpack._utils._helpers._data_get", __pyx_clineno, __pyx_lineno, __pyx_filename); 1523 | if (__Pyx_GetException(&__pyx_t_3, &__pyx_t_12, &__pyx_t_13) < 0) __PYX_ERR(0, 47, __pyx_L32_except_error) 1524 | __Pyx_GOTREF(__pyx_t_3); 1525 | __Pyx_GOTREF(__pyx_t_12); 1526 | __Pyx_GOTREF(__pyx_t_13); 1527 | 1528 | /* "backpack/_utils/_helpers.pyx":48 1529 | * target = target[segment] 1530 | * except (IndexError, KeyError, TypeError): 1531 | * try: # <<<<<<<<<<<<<< 1532 | * target = getattr(target, segment) 1533 | * except AttributeError: 1534 | */ 1535 | { 1536 | __Pyx_PyThreadState_declare 1537 | __Pyx_PyThreadState_assign 1538 | __Pyx_ExceptionSave(&__pyx_t_18, &__pyx_t_19, &__pyx_t_20); 1539 | __Pyx_XGOTREF(__pyx_t_18); 1540 | __Pyx_XGOTREF(__pyx_t_19); 1541 | __Pyx_XGOTREF(__pyx_t_20); 1542 | /*try:*/ { 1543 | 1544 | /* "backpack/_utils/_helpers.pyx":49 1545 | * except (IndexError, KeyError, TypeError): 1546 | * try: 1547 | * target = getattr(target, segment) # <<<<<<<<<<<<<< 1548 | * except AttributeError: 1549 | * return value(default) 1550 | */ 1551 | __pyx_t_14 = __Pyx_GetAttr(__pyx_v_target, __pyx_v_segment); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 49, __pyx_L40_error) 1552 | __Pyx_GOTREF(__pyx_t_14); 1553 | __Pyx_DECREF_SET(__pyx_v_target, __pyx_t_14); 1554 | __pyx_t_14 = 0; 1555 | 1556 | /* "backpack/_utils/_helpers.pyx":48 1557 | * target = target[segment] 1558 | * except (IndexError, KeyError, TypeError): 1559 | * try: # <<<<<<<<<<<<<< 1560 | * target = getattr(target, segment) 1561 | * except AttributeError: 1562 | */ 1563 | } 1564 | __Pyx_XDECREF(__pyx_t_18); __pyx_t_18 = 0; 1565 | __Pyx_XDECREF(__pyx_t_19); __pyx_t_19 = 0; 1566 | __Pyx_XDECREF(__pyx_t_20); __pyx_t_20 = 0; 1567 | goto __pyx_L47_try_end; 1568 | __pyx_L40_error:; 1569 | __Pyx_PyThreadState_assign 1570 | __Pyx_XDECREF(__pyx_t_17); __pyx_t_17 = 0; 1571 | __Pyx_XDECREF(__pyx_t_16); __pyx_t_16 = 0; 1572 | __Pyx_XDECREF(__pyx_t_15); __pyx_t_15 = 0; 1573 | __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0; 1574 | 1575 | /* "backpack/_utils/_helpers.pyx":50 1576 | * try: 1577 | * target = getattr(target, segment) 1578 | * except AttributeError: # <<<<<<<<<<<<<< 1579 | * return value(default) 1580 | * 1581 | */ 1582 | __pyx_t_11 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_AttributeError); 1583 | if (__pyx_t_11) { 1584 | __Pyx_AddTraceback("backpack._utils._helpers._data_get", __pyx_clineno, __pyx_lineno, __pyx_filename); 1585 | if (__Pyx_GetException(&__pyx_t_14, &__pyx_t_15, &__pyx_t_16) < 0) __PYX_ERR(0, 50, __pyx_L42_except_error) 1586 | __Pyx_GOTREF(__pyx_t_14); 1587 | __Pyx_GOTREF(__pyx_t_15); 1588 | __Pyx_GOTREF(__pyx_t_16); 1589 | 1590 | /* "backpack/_utils/_helpers.pyx":51 1591 | * target = getattr(target, segment) 1592 | * except AttributeError: 1593 | * return value(default) # <<<<<<<<<<<<<< 1594 | * 1595 | * return target 1596 | */ 1597 | __Pyx_XDECREF(__pyx_r); 1598 | __pyx_t_21 = __Pyx_GetModuleGlobalName(__pyx_n_s_value); if (unlikely(!__pyx_t_21)) __PYX_ERR(0, 51, __pyx_L42_except_error) 1599 | __Pyx_GOTREF(__pyx_t_21); 1600 | __pyx_t_22 = NULL; 1601 | if (CYTHON_COMPILING_IN_CPYTHON && unlikely(PyMethod_Check(__pyx_t_21))) { 1602 | __pyx_t_22 = PyMethod_GET_SELF(__pyx_t_21); 1603 | if (likely(__pyx_t_22)) { 1604 | PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_21); 1605 | __Pyx_INCREF(__pyx_t_22); 1606 | __Pyx_INCREF(function); 1607 | __Pyx_DECREF_SET(__pyx_t_21, function); 1608 | } 1609 | } 1610 | if (!__pyx_t_22) { 1611 | __pyx_t_17 = __Pyx_PyObject_CallOneArg(__pyx_t_21, __pyx_v_default); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 51, __pyx_L42_except_error) 1612 | __Pyx_GOTREF(__pyx_t_17); 1613 | } else { 1614 | __pyx_t_23 = PyTuple_New(1+1); if (unlikely(!__pyx_t_23)) __PYX_ERR(0, 51, __pyx_L42_except_error) 1615 | __Pyx_GOTREF(__pyx_t_23); 1616 | __Pyx_GIVEREF(__pyx_t_22); PyTuple_SET_ITEM(__pyx_t_23, 0, __pyx_t_22); __pyx_t_22 = NULL; 1617 | __Pyx_INCREF(__pyx_v_default); 1618 | __Pyx_GIVEREF(__pyx_v_default); 1619 | PyTuple_SET_ITEM(__pyx_t_23, 0+1, __pyx_v_default); 1620 | __pyx_t_17 = __Pyx_PyObject_Call(__pyx_t_21, __pyx_t_23, NULL); if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 51, __pyx_L42_except_error) 1621 | __Pyx_GOTREF(__pyx_t_17); 1622 | __Pyx_DECREF(__pyx_t_23); __pyx_t_23 = 0; 1623 | } 1624 | __Pyx_DECREF(__pyx_t_21); __pyx_t_21 = 0; 1625 | __pyx_r = __pyx_t_17; 1626 | __pyx_t_17 = 0; 1627 | __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; 1628 | __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; 1629 | __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; 1630 | __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; 1631 | __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0; 1632 | __Pyx_DECREF(__pyx_t_15); __pyx_t_15 = 0; 1633 | __Pyx_DECREF(__pyx_t_16); __pyx_t_16 = 0; 1634 | goto __pyx_L43_except_return; 1635 | } 1636 | goto __pyx_L42_except_error; 1637 | __pyx_L42_except_error:; 1638 | 1639 | /* "backpack/_utils/_helpers.pyx":48 1640 | * target = target[segment] 1641 | * except (IndexError, KeyError, TypeError): 1642 | * try: # <<<<<<<<<<<<<< 1643 | * target = getattr(target, segment) 1644 | * except AttributeError: 1645 | */ 1646 | __Pyx_PyThreadState_assign 1647 | __Pyx_XGIVEREF(__pyx_t_18); 1648 | __Pyx_XGIVEREF(__pyx_t_19); 1649 | __Pyx_XGIVEREF(__pyx_t_20); 1650 | __Pyx_ExceptionReset(__pyx_t_18, __pyx_t_19, __pyx_t_20); 1651 | goto __pyx_L32_except_error; 1652 | __pyx_L43_except_return:; 1653 | __Pyx_PyThreadState_assign 1654 | __Pyx_XGIVEREF(__pyx_t_18); 1655 | __Pyx_XGIVEREF(__pyx_t_19); 1656 | __Pyx_XGIVEREF(__pyx_t_20); 1657 | __Pyx_ExceptionReset(__pyx_t_18, __pyx_t_19, __pyx_t_20); 1658 | goto __pyx_L33_except_return; 1659 | __pyx_L47_try_end:; 1660 | } 1661 | __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; 1662 | __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0; 1663 | __Pyx_DECREF(__pyx_t_13); __pyx_t_13 = 0; 1664 | goto __pyx_L31_exception_handled; 1665 | } 1666 | goto __pyx_L32_except_error; 1667 | __pyx_L32_except_error:; 1668 | 1669 | /* "backpack/_utils/_helpers.pyx":45 1670 | * return value(default) 1671 | * else: 1672 | * try: # <<<<<<<<<<<<<< 1673 | * target = target[segment] 1674 | * except (IndexError, KeyError, TypeError): 1675 | */ 1676 | __Pyx_PyThreadState_assign 1677 | __Pyx_XGIVEREF(__pyx_t_8); 1678 | __Pyx_XGIVEREF(__pyx_t_9); 1679 | __Pyx_XGIVEREF(__pyx_t_10); 1680 | __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10); 1681 | goto __pyx_L1_error; 1682 | __pyx_L33_except_return:; 1683 | __Pyx_PyThreadState_assign 1684 | __Pyx_XGIVEREF(__pyx_t_8); 1685 | __Pyx_XGIVEREF(__pyx_t_9); 1686 | __Pyx_XGIVEREF(__pyx_t_10); 1687 | __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10); 1688 | goto __pyx_L0; 1689 | __pyx_L31_exception_handled:; 1690 | __Pyx_PyThreadState_assign 1691 | __Pyx_XGIVEREF(__pyx_t_8); 1692 | __Pyx_XGIVEREF(__pyx_t_9); 1693 | __Pyx_XGIVEREF(__pyx_t_10); 1694 | __Pyx_ExceptionReset(__pyx_t_8, __pyx_t_9, __pyx_t_10); 1695 | __pyx_L37_try_end:; 1696 | } 1697 | } 1698 | __pyx_L7:; 1699 | 1700 | /* "backpack/_utils/_helpers.pyx":33 1701 | * key = key.split('.') 1702 | * 1703 | * for segment in key: # <<<<<<<<<<<<<< 1704 | * if isinstance(target, (list, tuple)): 1705 | * try: 1706 | */ 1707 | } 1708 | __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; 1709 | 1710 | /* "backpack/_utils/_helpers.pyx":53 1711 | * return value(default) 1712 | * 1713 | * return target # <<<<<<<<<<<<<< 1714 | */ 1715 | __Pyx_XDECREF(__pyx_r); 1716 | __Pyx_INCREF(__pyx_v_target); 1717 | __pyx_r = __pyx_v_target; 1718 | goto __pyx_L0; 1719 | 1720 | /* "backpack/_utils/_helpers.pyx":26 1721 | * 1722 | * 1723 | * cdef _data_get(target, key, default=None): # <<<<<<<<<<<<<< 1724 | * if key is None: 1725 | * return target 1726 | */ 1727 | 1728 | /* function exit code */ 1729 | __pyx_L1_error:; 1730 | __Pyx_XDECREF(__pyx_t_3); 1731 | __Pyx_XDECREF(__pyx_t_4); 1732 | __Pyx_XDECREF(__pyx_t_12); 1733 | __Pyx_XDECREF(__pyx_t_13); 1734 | __Pyx_XDECREF(__pyx_t_14); 1735 | __Pyx_XDECREF(__pyx_t_15); 1736 | __Pyx_XDECREF(__pyx_t_16); 1737 | __Pyx_XDECREF(__pyx_t_17); 1738 | __Pyx_XDECREF(__pyx_t_21); 1739 | __Pyx_XDECREF(__pyx_t_22); 1740 | __Pyx_XDECREF(__pyx_t_23); 1741 | __Pyx_AddTraceback("backpack._utils._helpers._data_get", __pyx_clineno, __pyx_lineno, __pyx_filename); 1742 | __pyx_r = 0; 1743 | __pyx_L0:; 1744 | __Pyx_XDECREF(__pyx_v_segment); 1745 | __Pyx_XDECREF(__pyx_v_target); 1746 | __Pyx_XDECREF(__pyx_v_key); 1747 | __Pyx_XGIVEREF(__pyx_r); 1748 | __Pyx_RefNannyFinishContext(); 1749 | return __pyx_r; 1750 | } 1751 | 1752 | static PyMethodDef __pyx_methods[] = { 1753 | {0, 0, 0, 0} 1754 | }; 1755 | 1756 | #if PY_MAJOR_VERSION >= 3 1757 | static struct PyModuleDef __pyx_moduledef = { 1758 | #if PY_VERSION_HEX < 0x03020000 1759 | { PyObject_HEAD_INIT(NULL) NULL, 0, NULL }, 1760 | #else 1761 | PyModuleDef_HEAD_INIT, 1762 | #endif 1763 | "_helpers", 1764 | 0, /* m_doc */ 1765 | -1, /* m_size */ 1766 | __pyx_methods /* m_methods */, 1767 | NULL, /* m_reload */ 1768 | NULL, /* m_traverse */ 1769 | NULL, /* m_clear */ 1770 | NULL /* m_free */ 1771 | }; 1772 | #endif 1773 | 1774 | static __Pyx_StringTabEntry __pyx_string_tab[] = { 1775 | {&__pyx_kp_s_, __pyx_k_, sizeof(__pyx_k_), 0, 0, 1, 0}, 1776 | {&__pyx_n_s_AttributeError, __pyx_k_AttributeError, sizeof(__pyx_k_AttributeError), 0, 0, 1, 1}, 1777 | {&__pyx_n_s_IndexError, __pyx_k_IndexError, sizeof(__pyx_k_IndexError), 0, 0, 1, 1}, 1778 | {&__pyx_n_s_KeyError, __pyx_k_KeyError, sizeof(__pyx_k_KeyError), 0, 0, 1, 1}, 1779 | {&__pyx_n_s_TypeError, __pyx_k_TypeError, sizeof(__pyx_k_TypeError), 0, 0, 1, 1}, 1780 | {&__pyx_kp_s_Users_sebastien_src_sdispater_b, __pyx_k_Users_sebastien_src_sdispater_b, sizeof(__pyx_k_Users_sebastien_src_sdispater_b), 0, 0, 1, 0}, 1781 | {&__pyx_n_s_backpack__utils__helpers, __pyx_k_backpack__utils__helpers, sizeof(__pyx_k_backpack__utils__helpers), 0, 0, 1, 1}, 1782 | {&__pyx_n_s_data_get, __pyx_k_data_get, sizeof(__pyx_k_data_get), 0, 0, 1, 1}, 1783 | {&__pyx_n_s_default, __pyx_k_default, sizeof(__pyx_k_default), 0, 0, 1, 1}, 1784 | {&__pyx_n_s_key, __pyx_k_key, sizeof(__pyx_k_key), 0, 0, 1, 1}, 1785 | {&__pyx_n_s_main, __pyx_k_main, sizeof(__pyx_k_main), 0, 0, 1, 1}, 1786 | {&__pyx_n_s_split, __pyx_k_split, sizeof(__pyx_k_split), 0, 0, 1, 1}, 1787 | {&__pyx_n_s_target, __pyx_k_target, sizeof(__pyx_k_target), 0, 0, 1, 1}, 1788 | {&__pyx_n_s_test, __pyx_k_test, sizeof(__pyx_k_test), 0, 0, 1, 1}, 1789 | {&__pyx_n_s_val, __pyx_k_val, sizeof(__pyx_k_val), 0, 0, 1, 1}, 1790 | {&__pyx_n_s_value, __pyx_k_value, sizeof(__pyx_k_value), 0, 0, 1, 1}, 1791 | {0, 0, 0, 0, 0, 0, 0} 1792 | }; 1793 | static int __Pyx_InitCachedBuiltins(void) { 1794 | __pyx_builtin_IndexError = __Pyx_GetBuiltinName(__pyx_n_s_IndexError); if (!__pyx_builtin_IndexError) __PYX_ERR(0, 37, __pyx_L1_error) 1795 | __pyx_builtin_KeyError = __Pyx_GetBuiltinName(__pyx_n_s_KeyError); if (!__pyx_builtin_KeyError) __PYX_ERR(0, 47, __pyx_L1_error) 1796 | __pyx_builtin_TypeError = __Pyx_GetBuiltinName(__pyx_n_s_TypeError); if (!__pyx_builtin_TypeError) __PYX_ERR(0, 47, __pyx_L1_error) 1797 | __pyx_builtin_AttributeError = __Pyx_GetBuiltinName(__pyx_n_s_AttributeError); if (!__pyx_builtin_AttributeError) __PYX_ERR(0, 50, __pyx_L1_error) 1798 | return 0; 1799 | __pyx_L1_error:; 1800 | return -1; 1801 | } 1802 | 1803 | static int __Pyx_InitCachedConstants(void) { 1804 | __Pyx_RefNannyDeclarations 1805 | __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); 1806 | 1807 | /* "backpack/_utils/_helpers.pyx":31 1808 | * 1809 | * if not isinstance(key, list): 1810 | * key = key.split('.') # <<<<<<<<<<<<<< 1811 | * 1812 | * for segment in key: 1813 | */ 1814 | __pyx_tuple__2 = PyTuple_Pack(1, __pyx_kp_s_); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 31, __pyx_L1_error) 1815 | __Pyx_GOTREF(__pyx_tuple__2); 1816 | __Pyx_GIVEREF(__pyx_tuple__2); 1817 | 1818 | /* "backpack/_utils/_helpers.pyx":1 1819 | * def value(val): # <<<<<<<<<<<<<< 1820 | * if callable(val): 1821 | * return val() 1822 | */ 1823 | __pyx_tuple__3 = PyTuple_Pack(1, __pyx_n_s_val); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(0, 1, __pyx_L1_error) 1824 | __Pyx_GOTREF(__pyx_tuple__3); 1825 | __Pyx_GIVEREF(__pyx_tuple__3); 1826 | __pyx_codeobj__4 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__3, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_sebastien_src_sdispater_b, __pyx_n_s_value, 1, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__4)) __PYX_ERR(0, 1, __pyx_L1_error) 1827 | 1828 | /* "backpack/_utils/_helpers.pyx":8 1829 | * 1830 | * 1831 | * def data_get(target, key, default=None): # <<<<<<<<<<<<<< 1832 | * """ 1833 | * Get an item from a list, a dict or an object using "dot" notation. 1834 | */ 1835 | __pyx_tuple__5 = PyTuple_Pack(3, __pyx_n_s_target, __pyx_n_s_key, __pyx_n_s_default); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 8, __pyx_L1_error) 1836 | __Pyx_GOTREF(__pyx_tuple__5); 1837 | __Pyx_GIVEREF(__pyx_tuple__5); 1838 | __pyx_codeobj__6 = (PyObject*)__Pyx_PyCode_New(3, 0, 3, 0, 0, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__5, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_Users_sebastien_src_sdispater_b, __pyx_n_s_data_get, 8, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__6)) __PYX_ERR(0, 8, __pyx_L1_error) 1839 | __Pyx_RefNannyFinishContext(); 1840 | return 0; 1841 | __pyx_L1_error:; 1842 | __Pyx_RefNannyFinishContext(); 1843 | return -1; 1844 | } 1845 | 1846 | static int __Pyx_InitGlobals(void) { 1847 | if (__Pyx_InitStrings(__pyx_string_tab) < 0) __PYX_ERR(0, 1, __pyx_L1_error); 1848 | return 0; 1849 | __pyx_L1_error:; 1850 | return -1; 1851 | } 1852 | 1853 | #if PY_MAJOR_VERSION < 3 1854 | PyMODINIT_FUNC init_helpers(void); /*proto*/ 1855 | PyMODINIT_FUNC init_helpers(void) 1856 | #else 1857 | PyMODINIT_FUNC PyInit__helpers(void); /*proto*/ 1858 | PyMODINIT_FUNC PyInit__helpers(void) 1859 | #endif 1860 | { 1861 | PyObject *__pyx_t_1 = NULL; 1862 | __Pyx_RefNannyDeclarations 1863 | #if CYTHON_REFNANNY 1864 | __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); 1865 | if (!__Pyx_RefNanny) { 1866 | PyErr_Clear(); 1867 | __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); 1868 | if (!__Pyx_RefNanny) 1869 | Py_FatalError("failed to import 'refnanny' module"); 1870 | } 1871 | #endif 1872 | __Pyx_RefNannySetupContext("PyMODINIT_FUNC PyInit__helpers(void)", 0); 1873 | if (__Pyx_check_binary_version() < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1874 | __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) 1875 | __pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) 1876 | __pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) 1877 | #ifdef __Pyx_CyFunction_USED 1878 | if (__pyx_CyFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1879 | #endif 1880 | #ifdef __Pyx_FusedFunction_USED 1881 | if (__pyx_FusedFunction_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1882 | #endif 1883 | #ifdef __Pyx_Coroutine_USED 1884 | if (__pyx_Coroutine_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1885 | #endif 1886 | #ifdef __Pyx_Generator_USED 1887 | if (__pyx_Generator_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1888 | #endif 1889 | #ifdef __Pyx_StopAsyncIteration_USED 1890 | if (__pyx_StopAsyncIteration_init() < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1891 | #endif 1892 | /*--- Library function declarations ---*/ 1893 | /*--- Threads initialization code ---*/ 1894 | #if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS 1895 | #ifdef WITH_THREAD /* Python build with threading support? */ 1896 | PyEval_InitThreads(); 1897 | #endif 1898 | #endif 1899 | /*--- Module creation code ---*/ 1900 | #if PY_MAJOR_VERSION < 3 1901 | __pyx_m = Py_InitModule4("_helpers", __pyx_methods, 0, 0, PYTHON_API_VERSION); Py_XINCREF(__pyx_m); 1902 | #else 1903 | __pyx_m = PyModule_Create(&__pyx_moduledef); 1904 | #endif 1905 | if (unlikely(!__pyx_m)) __PYX_ERR(0, 1, __pyx_L1_error) 1906 | __pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) 1907 | Py_INCREF(__pyx_d); 1908 | __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) 1909 | #if CYTHON_COMPILING_IN_PYPY 1910 | Py_INCREF(__pyx_b); 1911 | #endif 1912 | if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error); 1913 | /*--- Initialize various global constants etc. ---*/ 1914 | if (__Pyx_InitGlobals() < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1915 | #if PY_MAJOR_VERSION < 3 && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) 1916 | if (__Pyx_init_sys_getdefaultencoding_params() < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1917 | #endif 1918 | if (__pyx_module_is_main_backpack___utils___helpers) { 1919 | if (PyObject_SetAttrString(__pyx_m, "__name__", __pyx_n_s_main) < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1920 | } 1921 | #if PY_MAJOR_VERSION >= 3 1922 | { 1923 | PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) 1924 | if (!PyDict_GetItemString(modules, "backpack._utils._helpers")) { 1925 | if (unlikely(PyDict_SetItemString(modules, "backpack._utils._helpers", __pyx_m) < 0)) __PYX_ERR(0, 1, __pyx_L1_error) 1926 | } 1927 | } 1928 | #endif 1929 | /*--- Builtin init code ---*/ 1930 | if (__Pyx_InitCachedBuiltins() < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1931 | /*--- Constants init code ---*/ 1932 | if (__Pyx_InitCachedConstants() < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1933 | /*--- Global init code ---*/ 1934 | /*--- Variable export code ---*/ 1935 | /*--- Function export code ---*/ 1936 | /*--- Type init code ---*/ 1937 | /*--- Type import code ---*/ 1938 | /*--- Variable import code ---*/ 1939 | /*--- Function import code ---*/ 1940 | /*--- Execution code ---*/ 1941 | #if defined(__Pyx_Generator_USED) || defined(__Pyx_Coroutine_USED) 1942 | if (__Pyx_patch_abc() < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1943 | #endif 1944 | 1945 | /* "backpack/_utils/_helpers.pyx":1 1946 | * def value(val): # <<<<<<<<<<<<<< 1947 | * if callable(val): 1948 | * return val() 1949 | */ 1950 | __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8backpack_6_utils_8_helpers_1value, NULL, __pyx_n_s_backpack__utils__helpers); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) 1951 | __Pyx_GOTREF(__pyx_t_1); 1952 | if (PyDict_SetItem(__pyx_d, __pyx_n_s_value, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1953 | __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; 1954 | 1955 | /* "backpack/_utils/_helpers.pyx":8 1956 | * 1957 | * 1958 | * def data_get(target, key, default=None): # <<<<<<<<<<<<<< 1959 | * """ 1960 | * Get an item from a list, a dict or an object using "dot" notation. 1961 | */ 1962 | __pyx_t_1 = PyCFunction_NewEx(&__pyx_mdef_8backpack_6_utils_8_helpers_3data_get, NULL, __pyx_n_s_backpack__utils__helpers); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 8, __pyx_L1_error) 1963 | __Pyx_GOTREF(__pyx_t_1); 1964 | if (PyDict_SetItem(__pyx_d, __pyx_n_s_data_get, __pyx_t_1) < 0) __PYX_ERR(0, 8, __pyx_L1_error) 1965 | __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; 1966 | 1967 | /* "backpack/_utils/_helpers.pyx":1 1968 | * def value(val): # <<<<<<<<<<<<<< 1969 | * if callable(val): 1970 | * return val() 1971 | */ 1972 | __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) 1973 | __Pyx_GOTREF(__pyx_t_1); 1974 | if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_1) < 0) __PYX_ERR(0, 1, __pyx_L1_error) 1975 | __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; 1976 | 1977 | /*--- Wrapped vars code ---*/ 1978 | 1979 | goto __pyx_L0; 1980 | __pyx_L1_error:; 1981 | __Pyx_XDECREF(__pyx_t_1); 1982 | if (__pyx_m) { 1983 | if (__pyx_d) { 1984 | __Pyx_AddTraceback("init backpack._utils._helpers", __pyx_clineno, __pyx_lineno, __pyx_filename); 1985 | } 1986 | Py_DECREF(__pyx_m); __pyx_m = 0; 1987 | } else if (!PyErr_Occurred()) { 1988 | PyErr_SetString(PyExc_ImportError, "init backpack._utils._helpers"); 1989 | } 1990 | __pyx_L0:; 1991 | __Pyx_RefNannyFinishContext(); 1992 | #if PY_MAJOR_VERSION < 3 1993 | return; 1994 | #else 1995 | return __pyx_m; 1996 | #endif 1997 | } 1998 | 1999 | /* --- Runtime support code --- */ 2000 | /* Refnanny */ 2001 | #if CYTHON_REFNANNY 2002 | static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { 2003 | PyObject *m = NULL, *p = NULL; 2004 | void *r = NULL; 2005 | m = PyImport_ImportModule((char *)modname); 2006 | if (!m) goto end; 2007 | p = PyObject_GetAttrString(m, (char *)"RefNannyAPI"); 2008 | if (!p) goto end; 2009 | r = PyLong_AsVoidPtr(p); 2010 | end: 2011 | Py_XDECREF(p); 2012 | Py_XDECREF(m); 2013 | return (__Pyx_RefNannyAPIStruct *)r; 2014 | } 2015 | #endif 2016 | 2017 | /* GetBuiltinName */ 2018 | static PyObject *__Pyx_GetBuiltinName(PyObject *name) { 2019 | PyObject* result = __Pyx_PyObject_GetAttrStr(__pyx_b, name); 2020 | if (unlikely(!result)) { 2021 | PyErr_Format(PyExc_NameError, 2022 | #if PY_MAJOR_VERSION >= 3 2023 | "name '%U' is not defined", name); 2024 | #else 2025 | "name '%.200s' is not defined", PyString_AS_STRING(name)); 2026 | #endif 2027 | } 2028 | return result; 2029 | } 2030 | 2031 | /* PyObjectCall */ 2032 | #if CYTHON_COMPILING_IN_CPYTHON 2033 | static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw) { 2034 | PyObject *result; 2035 | ternaryfunc call = func->ob_type->tp_call; 2036 | if (unlikely(!call)) 2037 | return PyObject_Call(func, arg, kw); 2038 | if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) 2039 | return NULL; 2040 | result = (*call)(func, arg, kw); 2041 | Py_LeaveRecursiveCall(); 2042 | if (unlikely(!result) && unlikely(!PyErr_Occurred())) { 2043 | PyErr_SetString( 2044 | PyExc_SystemError, 2045 | "NULL result without error in PyObject_Call"); 2046 | } 2047 | return result; 2048 | } 2049 | #endif 2050 | 2051 | /* PyObjectCallMethO */ 2052 | #if CYTHON_COMPILING_IN_CPYTHON 2053 | static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { 2054 | PyObject *self, *result; 2055 | PyCFunction cfunc; 2056 | cfunc = PyCFunction_GET_FUNCTION(func); 2057 | self = PyCFunction_GET_SELF(func); 2058 | if (unlikely(Py_EnterRecursiveCall((char*)" while calling a Python object"))) 2059 | return NULL; 2060 | result = cfunc(self, arg); 2061 | Py_LeaveRecursiveCall(); 2062 | if (unlikely(!result) && unlikely(!PyErr_Occurred())) { 2063 | PyErr_SetString( 2064 | PyExc_SystemError, 2065 | "NULL result without error in PyObject_Call"); 2066 | } 2067 | return result; 2068 | } 2069 | #endif 2070 | 2071 | /* PyObjectCallOneArg */ 2072 | #if CYTHON_COMPILING_IN_CPYTHON 2073 | static PyObject* __Pyx__PyObject_CallOneArg(PyObject *func, PyObject *arg) { 2074 | PyObject *result; 2075 | PyObject *args = PyTuple_New(1); 2076 | if (unlikely(!args)) return NULL; 2077 | Py_INCREF(arg); 2078 | PyTuple_SET_ITEM(args, 0, arg); 2079 | result = __Pyx_PyObject_Call(func, args, NULL); 2080 | Py_DECREF(args); 2081 | return result; 2082 | } 2083 | static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { 2084 | #ifdef __Pyx_CyFunction_USED 2085 | if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) { 2086 | #else 2087 | if (likely(PyCFunction_Check(func))) { 2088 | #endif 2089 | if (likely(PyCFunction_GET_FLAGS(func) & METH_O)) { 2090 | return __Pyx_PyObject_CallMethO(func, arg); 2091 | } 2092 | } 2093 | return __Pyx__PyObject_CallOneArg(func, arg); 2094 | } 2095 | #else 2096 | static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { 2097 | PyObject *result; 2098 | PyObject *args = PyTuple_Pack(1, arg); 2099 | if (unlikely(!args)) return NULL; 2100 | result = __Pyx_PyObject_Call(func, args, NULL); 2101 | Py_DECREF(args); 2102 | return result; 2103 | } 2104 | #endif 2105 | 2106 | /* PyObjectCallNoArg */ 2107 | #if CYTHON_COMPILING_IN_CPYTHON 2108 | static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { 2109 | #ifdef __Pyx_CyFunction_USED 2110 | if (likely(PyCFunction_Check(func) || PyObject_TypeCheck(func, __pyx_CyFunctionType))) { 2111 | #else 2112 | if (likely(PyCFunction_Check(func))) { 2113 | #endif 2114 | if (likely(PyCFunction_GET_FLAGS(func) & METH_NOARGS)) { 2115 | return __Pyx_PyObject_CallMethO(func, NULL); 2116 | } 2117 | } 2118 | return __Pyx_PyObject_Call(func, __pyx_empty_tuple, NULL); 2119 | } 2120 | #endif 2121 | 2122 | /* RaiseArgTupleInvalid */ 2123 | static void __Pyx_RaiseArgtupleInvalid( 2124 | const char* func_name, 2125 | int exact, 2126 | Py_ssize_t num_min, 2127 | Py_ssize_t num_max, 2128 | Py_ssize_t num_found) 2129 | { 2130 | Py_ssize_t num_expected; 2131 | const char *more_or_less; 2132 | if (num_found < num_min) { 2133 | num_expected = num_min; 2134 | more_or_less = "at least"; 2135 | } else { 2136 | num_expected = num_max; 2137 | more_or_less = "at most"; 2138 | } 2139 | if (exact) { 2140 | more_or_less = "exactly"; 2141 | } 2142 | PyErr_Format(PyExc_TypeError, 2143 | "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", 2144 | func_name, more_or_less, num_expected, 2145 | (num_expected == 1) ? "" : "s", num_found); 2146 | } 2147 | 2148 | /* RaiseDoubleKeywords */ 2149 | static void __Pyx_RaiseDoubleKeywordsError( 2150 | const char* func_name, 2151 | PyObject* kw_name) 2152 | { 2153 | PyErr_Format(PyExc_TypeError, 2154 | #if PY_MAJOR_VERSION >= 3 2155 | "%s() got multiple values for keyword argument '%U'", func_name, kw_name); 2156 | #else 2157 | "%s() got multiple values for keyword argument '%s'", func_name, 2158 | PyString_AsString(kw_name)); 2159 | #endif 2160 | } 2161 | 2162 | /* ParseKeywords */ 2163 | static int __Pyx_ParseOptionalKeywords( 2164 | PyObject *kwds, 2165 | PyObject **argnames[], 2166 | PyObject *kwds2, 2167 | PyObject *values[], 2168 | Py_ssize_t num_pos_args, 2169 | const char* function_name) 2170 | { 2171 | PyObject *key = 0, *value = 0; 2172 | Py_ssize_t pos = 0; 2173 | PyObject*** name; 2174 | PyObject*** first_kw_arg = argnames + num_pos_args; 2175 | while (PyDict_Next(kwds, &pos, &key, &value)) { 2176 | name = first_kw_arg; 2177 | while (*name && (**name != key)) name++; 2178 | if (*name) { 2179 | values[name-argnames] = value; 2180 | continue; 2181 | } 2182 | name = first_kw_arg; 2183 | #if PY_MAJOR_VERSION < 3 2184 | if (likely(PyString_CheckExact(key)) || likely(PyString_Check(key))) { 2185 | while (*name) { 2186 | if ((CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**name) == PyString_GET_SIZE(key)) 2187 | && _PyString_Eq(**name, key)) { 2188 | values[name-argnames] = value; 2189 | break; 2190 | } 2191 | name++; 2192 | } 2193 | if (*name) continue; 2194 | else { 2195 | PyObject*** argname = argnames; 2196 | while (argname != first_kw_arg) { 2197 | if ((**argname == key) || ( 2198 | (CYTHON_COMPILING_IN_PYPY || PyString_GET_SIZE(**argname) == PyString_GET_SIZE(key)) 2199 | && _PyString_Eq(**argname, key))) { 2200 | goto arg_passed_twice; 2201 | } 2202 | argname++; 2203 | } 2204 | } 2205 | } else 2206 | #endif 2207 | if (likely(PyUnicode_Check(key))) { 2208 | while (*name) { 2209 | int cmp = (**name == key) ? 0 : 2210 | #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 2211 | (PyUnicode_GET_SIZE(**name) != PyUnicode_GET_SIZE(key)) ? 1 : 2212 | #endif 2213 | PyUnicode_Compare(**name, key); 2214 | if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; 2215 | if (cmp == 0) { 2216 | values[name-argnames] = value; 2217 | break; 2218 | } 2219 | name++; 2220 | } 2221 | if (*name) continue; 2222 | else { 2223 | PyObject*** argname = argnames; 2224 | while (argname != first_kw_arg) { 2225 | int cmp = (**argname == key) ? 0 : 2226 | #if !CYTHON_COMPILING_IN_PYPY && PY_MAJOR_VERSION >= 3 2227 | (PyUnicode_GET_SIZE(**argname) != PyUnicode_GET_SIZE(key)) ? 1 : 2228 | #endif 2229 | PyUnicode_Compare(**argname, key); 2230 | if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; 2231 | if (cmp == 0) goto arg_passed_twice; 2232 | argname++; 2233 | } 2234 | } 2235 | } else 2236 | goto invalid_keyword_type; 2237 | if (kwds2) { 2238 | if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; 2239 | } else { 2240 | goto invalid_keyword; 2241 | } 2242 | } 2243 | return 0; 2244 | arg_passed_twice: 2245 | __Pyx_RaiseDoubleKeywordsError(function_name, key); 2246 | goto bad; 2247 | invalid_keyword_type: 2248 | PyErr_Format(PyExc_TypeError, 2249 | "%.200s() keywords must be strings", function_name); 2250 | goto bad; 2251 | invalid_keyword: 2252 | PyErr_Format(PyExc_TypeError, 2253 | #if PY_MAJOR_VERSION < 3 2254 | "%.200s() got an unexpected keyword argument '%.200s'", 2255 | function_name, PyString_AsString(key)); 2256 | #else 2257 | "%s() got an unexpected keyword argument '%U'", 2258 | function_name, key); 2259 | #endif 2260 | bad: 2261 | return -1; 2262 | } 2263 | 2264 | /* SaveResetException */ 2265 | #if CYTHON_COMPILING_IN_CPYTHON 2266 | static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { 2267 | *type = tstate->exc_type; 2268 | *value = tstate->exc_value; 2269 | *tb = tstate->exc_traceback; 2270 | Py_XINCREF(*type); 2271 | Py_XINCREF(*value); 2272 | Py_XINCREF(*tb); 2273 | } 2274 | static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { 2275 | PyObject *tmp_type, *tmp_value, *tmp_tb; 2276 | tmp_type = tstate->exc_type; 2277 | tmp_value = tstate->exc_value; 2278 | tmp_tb = tstate->exc_traceback; 2279 | tstate->exc_type = type; 2280 | tstate->exc_value = value; 2281 | tstate->exc_traceback = tb; 2282 | Py_XDECREF(tmp_type); 2283 | Py_XDECREF(tmp_value); 2284 | Py_XDECREF(tmp_tb); 2285 | } 2286 | #endif 2287 | 2288 | /* PyErrExceptionMatches */ 2289 | #if CYTHON_COMPILING_IN_CPYTHON 2290 | static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err) { 2291 | PyObject *exc_type = tstate->curexc_type; 2292 | if (exc_type == err) return 1; 2293 | if (unlikely(!exc_type)) return 0; 2294 | return PyErr_GivenExceptionMatches(exc_type, err); 2295 | } 2296 | #endif 2297 | 2298 | /* GetException */ 2299 | #if CYTHON_COMPILING_IN_CPYTHON 2300 | static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { 2301 | #else 2302 | static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { 2303 | #endif 2304 | PyObject *local_type, *local_value, *local_tb; 2305 | #if CYTHON_COMPILING_IN_CPYTHON 2306 | PyObject *tmp_type, *tmp_value, *tmp_tb; 2307 | local_type = tstate->curexc_type; 2308 | local_value = tstate->curexc_value; 2309 | local_tb = tstate->curexc_traceback; 2310 | tstate->curexc_type = 0; 2311 | tstate->curexc_value = 0; 2312 | tstate->curexc_traceback = 0; 2313 | #else 2314 | PyErr_Fetch(&local_type, &local_value, &local_tb); 2315 | #endif 2316 | PyErr_NormalizeException(&local_type, &local_value, &local_tb); 2317 | #if CYTHON_COMPILING_IN_CPYTHON 2318 | if (unlikely(tstate->curexc_type)) 2319 | #else 2320 | if (unlikely(PyErr_Occurred())) 2321 | #endif 2322 | goto bad; 2323 | #if PY_MAJOR_VERSION >= 3 2324 | if (local_tb) { 2325 | if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) 2326 | goto bad; 2327 | } 2328 | #endif 2329 | Py_XINCREF(local_tb); 2330 | Py_XINCREF(local_type); 2331 | Py_XINCREF(local_value); 2332 | *type = local_type; 2333 | *value = local_value; 2334 | *tb = local_tb; 2335 | #if CYTHON_COMPILING_IN_CPYTHON 2336 | tmp_type = tstate->exc_type; 2337 | tmp_value = tstate->exc_value; 2338 | tmp_tb = tstate->exc_traceback; 2339 | tstate->exc_type = local_type; 2340 | tstate->exc_value = local_value; 2341 | tstate->exc_traceback = local_tb; 2342 | Py_XDECREF(tmp_type); 2343 | Py_XDECREF(tmp_value); 2344 | Py_XDECREF(tmp_tb); 2345 | #else 2346 | PyErr_SetExcInfo(local_type, local_value, local_tb); 2347 | #endif 2348 | return 0; 2349 | bad: 2350 | *type = 0; 2351 | *value = 0; 2352 | *tb = 0; 2353 | Py_XDECREF(local_type); 2354 | Py_XDECREF(local_value); 2355 | Py_XDECREF(local_tb); 2356 | return -1; 2357 | } 2358 | 2359 | /* GetModuleGlobalName */ 2360 | static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) { 2361 | PyObject *result; 2362 | #if CYTHON_COMPILING_IN_CPYTHON 2363 | result = PyDict_GetItem(__pyx_d, name); 2364 | if (likely(result)) { 2365 | Py_INCREF(result); 2366 | } else { 2367 | #else 2368 | result = PyObject_GetItem(__pyx_d, name); 2369 | if (!result) { 2370 | PyErr_Clear(); 2371 | #endif 2372 | result = __Pyx_GetBuiltinName(name); 2373 | } 2374 | return result; 2375 | } 2376 | 2377 | /* GetAttr */ 2378 | static CYTHON_INLINE PyObject *__Pyx_GetAttr(PyObject *o, PyObject *n) { 2379 | #if CYTHON_COMPILING_IN_CPYTHON 2380 | #if PY_MAJOR_VERSION >= 3 2381 | if (likely(PyUnicode_Check(n))) 2382 | #else 2383 | if (likely(PyString_Check(n))) 2384 | #endif 2385 | return __Pyx_PyObject_GetAttrStr(o, n); 2386 | #endif 2387 | return PyObject_GetAttr(o, n); 2388 | } 2389 | 2390 | /* CodeObjectCache */ 2391 | static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { 2392 | int start = 0, mid = 0, end = count - 1; 2393 | if (end >= 0 && code_line > entries[end].code_line) { 2394 | return count; 2395 | } 2396 | while (start < end) { 2397 | mid = start + (end - start) / 2; 2398 | if (code_line < entries[mid].code_line) { 2399 | end = mid; 2400 | } else if (code_line > entries[mid].code_line) { 2401 | start = mid + 1; 2402 | } else { 2403 | return mid; 2404 | } 2405 | } 2406 | if (code_line <= entries[mid].code_line) { 2407 | return mid; 2408 | } else { 2409 | return mid + 1; 2410 | } 2411 | } 2412 | static PyCodeObject *__pyx_find_code_object(int code_line) { 2413 | PyCodeObject* code_object; 2414 | int pos; 2415 | if (unlikely(!code_line) || unlikely(!__pyx_code_cache.entries)) { 2416 | return NULL; 2417 | } 2418 | pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); 2419 | if (unlikely(pos >= __pyx_code_cache.count) || unlikely(__pyx_code_cache.entries[pos].code_line != code_line)) { 2420 | return NULL; 2421 | } 2422 | code_object = __pyx_code_cache.entries[pos].code_object; 2423 | Py_INCREF(code_object); 2424 | return code_object; 2425 | } 2426 | static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) { 2427 | int pos, i; 2428 | __Pyx_CodeObjectCacheEntry* entries = __pyx_code_cache.entries; 2429 | if (unlikely(!code_line)) { 2430 | return; 2431 | } 2432 | if (unlikely(!entries)) { 2433 | entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); 2434 | if (likely(entries)) { 2435 | __pyx_code_cache.entries = entries; 2436 | __pyx_code_cache.max_count = 64; 2437 | __pyx_code_cache.count = 1; 2438 | entries[0].code_line = code_line; 2439 | entries[0].code_object = code_object; 2440 | Py_INCREF(code_object); 2441 | } 2442 | return; 2443 | } 2444 | pos = __pyx_bisect_code_objects(__pyx_code_cache.entries, __pyx_code_cache.count, code_line); 2445 | if ((pos < __pyx_code_cache.count) && unlikely(__pyx_code_cache.entries[pos].code_line == code_line)) { 2446 | PyCodeObject* tmp = entries[pos].code_object; 2447 | entries[pos].code_object = code_object; 2448 | Py_DECREF(tmp); 2449 | return; 2450 | } 2451 | if (__pyx_code_cache.count == __pyx_code_cache.max_count) { 2452 | int new_max = __pyx_code_cache.max_count + 64; 2453 | entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( 2454 | __pyx_code_cache.entries, (size_t)new_max*sizeof(__Pyx_CodeObjectCacheEntry)); 2455 | if (unlikely(!entries)) { 2456 | return; 2457 | } 2458 | __pyx_code_cache.entries = entries; 2459 | __pyx_code_cache.max_count = new_max; 2460 | } 2461 | for (i=__pyx_code_cache.count; i>pos; i--) { 2462 | entries[i] = entries[i-1]; 2463 | } 2464 | entries[pos].code_line = code_line; 2465 | entries[pos].code_object = code_object; 2466 | __pyx_code_cache.count++; 2467 | Py_INCREF(code_object); 2468 | } 2469 | 2470 | /* AddTraceback */ 2471 | #include "compile.h" 2472 | #include "frameobject.h" 2473 | #include "traceback.h" 2474 | static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( 2475 | const char *funcname, int c_line, 2476 | int py_line, const char *filename) { 2477 | PyCodeObject *py_code = 0; 2478 | PyObject *py_srcfile = 0; 2479 | PyObject *py_funcname = 0; 2480 | #if PY_MAJOR_VERSION < 3 2481 | py_srcfile = PyString_FromString(filename); 2482 | #else 2483 | py_srcfile = PyUnicode_FromString(filename); 2484 | #endif 2485 | if (!py_srcfile) goto bad; 2486 | if (c_line) { 2487 | #if PY_MAJOR_VERSION < 3 2488 | py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); 2489 | #else 2490 | py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); 2491 | #endif 2492 | } 2493 | else { 2494 | #if PY_MAJOR_VERSION < 3 2495 | py_funcname = PyString_FromString(funcname); 2496 | #else 2497 | py_funcname = PyUnicode_FromString(funcname); 2498 | #endif 2499 | } 2500 | if (!py_funcname) goto bad; 2501 | py_code = __Pyx_PyCode_New( 2502 | 0, 2503 | 0, 2504 | 0, 2505 | 0, 2506 | 0, 2507 | __pyx_empty_bytes, /*PyObject *code,*/ 2508 | __pyx_empty_tuple, /*PyObject *consts,*/ 2509 | __pyx_empty_tuple, /*PyObject *names,*/ 2510 | __pyx_empty_tuple, /*PyObject *varnames,*/ 2511 | __pyx_empty_tuple, /*PyObject *freevars,*/ 2512 | __pyx_empty_tuple, /*PyObject *cellvars,*/ 2513 | py_srcfile, /*PyObject *filename,*/ 2514 | py_funcname, /*PyObject *name,*/ 2515 | py_line, 2516 | __pyx_empty_bytes /*PyObject *lnotab*/ 2517 | ); 2518 | Py_DECREF(py_srcfile); 2519 | Py_DECREF(py_funcname); 2520 | return py_code; 2521 | bad: 2522 | Py_XDECREF(py_srcfile); 2523 | Py_XDECREF(py_funcname); 2524 | return NULL; 2525 | } 2526 | static void __Pyx_AddTraceback(const char *funcname, int c_line, 2527 | int py_line, const char *filename) { 2528 | PyCodeObject *py_code = 0; 2529 | PyFrameObject *py_frame = 0; 2530 | py_code = __pyx_find_code_object(c_line ? c_line : py_line); 2531 | if (!py_code) { 2532 | py_code = __Pyx_CreateCodeObjectForTraceback( 2533 | funcname, c_line, py_line, filename); 2534 | if (!py_code) goto bad; 2535 | __pyx_insert_code_object(c_line ? c_line : py_line, py_code); 2536 | } 2537 | py_frame = PyFrame_New( 2538 | PyThreadState_GET(), /*PyThreadState *tstate,*/ 2539 | py_code, /*PyCodeObject *code,*/ 2540 | __pyx_d, /*PyObject *globals,*/ 2541 | 0 /*PyObject *locals*/ 2542 | ); 2543 | if (!py_frame) goto bad; 2544 | py_frame->f_lineno = py_line; 2545 | PyTraceBack_Here(py_frame); 2546 | bad: 2547 | Py_XDECREF(py_code); 2548 | Py_XDECREF(py_frame); 2549 | } 2550 | 2551 | /* CIntToPy */ 2552 | static CYTHON_INLINE PyObject* __Pyx_PyInt_From_long(long value) { 2553 | const long neg_one = (long) -1, const_zero = (long) 0; 2554 | const int is_unsigned = neg_one > const_zero; 2555 | if (is_unsigned) { 2556 | if (sizeof(long) < sizeof(long)) { 2557 | return PyInt_FromLong((long) value); 2558 | } else if (sizeof(long) <= sizeof(unsigned long)) { 2559 | return PyLong_FromUnsignedLong((unsigned long) value); 2560 | } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { 2561 | return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); 2562 | } 2563 | } else { 2564 | if (sizeof(long) <= sizeof(long)) { 2565 | return PyInt_FromLong((long) value); 2566 | } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { 2567 | return PyLong_FromLongLong((PY_LONG_LONG) value); 2568 | } 2569 | } 2570 | { 2571 | int one = 1; int little = (int)*(unsigned char *)&one; 2572 | unsigned char *bytes = (unsigned char *)&value; 2573 | return _PyLong_FromByteArray(bytes, sizeof(long), 2574 | little, !is_unsigned); 2575 | } 2576 | } 2577 | 2578 | /* CIntFromPyVerify */ 2579 | #define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ 2580 | __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) 2581 | #define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ 2582 | __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) 2583 | #define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ 2584 | {\ 2585 | func_type value = func_value;\ 2586 | if (sizeof(target_type) < sizeof(func_type)) {\ 2587 | if (unlikely(value != (func_type) (target_type) value)) {\ 2588 | func_type zero = 0;\ 2589 | if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ 2590 | return (target_type) -1;\ 2591 | if (is_unsigned && unlikely(value < zero))\ 2592 | goto raise_neg_overflow;\ 2593 | else\ 2594 | goto raise_overflow;\ 2595 | }\ 2596 | }\ 2597 | return (target_type) value;\ 2598 | } 2599 | 2600 | /* CIntFromPy */ 2601 | static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) { 2602 | const long neg_one = (long) -1, const_zero = (long) 0; 2603 | const int is_unsigned = neg_one > const_zero; 2604 | #if PY_MAJOR_VERSION < 3 2605 | if (likely(PyInt_Check(x))) { 2606 | if (sizeof(long) < sizeof(long)) { 2607 | __PYX_VERIFY_RETURN_INT(long, long, PyInt_AS_LONG(x)) 2608 | } else { 2609 | long val = PyInt_AS_LONG(x); 2610 | if (is_unsigned && unlikely(val < 0)) { 2611 | goto raise_neg_overflow; 2612 | } 2613 | return (long) val; 2614 | } 2615 | } else 2616 | #endif 2617 | if (likely(PyLong_Check(x))) { 2618 | if (is_unsigned) { 2619 | #if CYTHON_USE_PYLONG_INTERNALS 2620 | const digit* digits = ((PyLongObject*)x)->ob_digit; 2621 | switch (Py_SIZE(x)) { 2622 | case 0: return (long) 0; 2623 | case 1: __PYX_VERIFY_RETURN_INT(long, digit, digits[0]) 2624 | case 2: 2625 | if (8 * sizeof(long) > 1 * PyLong_SHIFT) { 2626 | if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { 2627 | __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2628 | } else if (8 * sizeof(long) >= 2 * PyLong_SHIFT) { 2629 | return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); 2630 | } 2631 | } 2632 | break; 2633 | case 3: 2634 | if (8 * sizeof(long) > 2 * PyLong_SHIFT) { 2635 | if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { 2636 | __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2637 | } else if (8 * sizeof(long) >= 3 * PyLong_SHIFT) { 2638 | return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); 2639 | } 2640 | } 2641 | break; 2642 | case 4: 2643 | if (8 * sizeof(long) > 3 * PyLong_SHIFT) { 2644 | if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { 2645 | __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2646 | } else if (8 * sizeof(long) >= 4 * PyLong_SHIFT) { 2647 | return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); 2648 | } 2649 | } 2650 | break; 2651 | } 2652 | #endif 2653 | #if CYTHON_COMPILING_IN_CPYTHON 2654 | if (unlikely(Py_SIZE(x) < 0)) { 2655 | goto raise_neg_overflow; 2656 | } 2657 | #else 2658 | { 2659 | int result = PyObject_RichCompareBool(x, Py_False, Py_LT); 2660 | if (unlikely(result < 0)) 2661 | return (long) -1; 2662 | if (unlikely(result == 1)) 2663 | goto raise_neg_overflow; 2664 | } 2665 | #endif 2666 | if (sizeof(long) <= sizeof(unsigned long)) { 2667 | __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) 2668 | } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { 2669 | __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) 2670 | } 2671 | } else { 2672 | #if CYTHON_USE_PYLONG_INTERNALS 2673 | const digit* digits = ((PyLongObject*)x)->ob_digit; 2674 | switch (Py_SIZE(x)) { 2675 | case 0: return (long) 0; 2676 | case -1: __PYX_VERIFY_RETURN_INT(long, sdigit, (sdigit) (-(sdigit)digits[0])) 2677 | case 1: __PYX_VERIFY_RETURN_INT(long, digit, +digits[0]) 2678 | case -2: 2679 | if (8 * sizeof(long) - 1 > 1 * PyLong_SHIFT) { 2680 | if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { 2681 | __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2682 | } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { 2683 | return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); 2684 | } 2685 | } 2686 | break; 2687 | case 2: 2688 | if (8 * sizeof(long) > 1 * PyLong_SHIFT) { 2689 | if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { 2690 | __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2691 | } else if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { 2692 | return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); 2693 | } 2694 | } 2695 | break; 2696 | case -3: 2697 | if (8 * sizeof(long) - 1 > 2 * PyLong_SHIFT) { 2698 | if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { 2699 | __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2700 | } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { 2701 | return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); 2702 | } 2703 | } 2704 | break; 2705 | case 3: 2706 | if (8 * sizeof(long) > 2 * PyLong_SHIFT) { 2707 | if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { 2708 | __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2709 | } else if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { 2710 | return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); 2711 | } 2712 | } 2713 | break; 2714 | case -4: 2715 | if (8 * sizeof(long) - 1 > 3 * PyLong_SHIFT) { 2716 | if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { 2717 | __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2718 | } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { 2719 | return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); 2720 | } 2721 | } 2722 | break; 2723 | case 4: 2724 | if (8 * sizeof(long) > 3 * PyLong_SHIFT) { 2725 | if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { 2726 | __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2727 | } else if (8 * sizeof(long) - 1 > 4 * PyLong_SHIFT) { 2728 | return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); 2729 | } 2730 | } 2731 | break; 2732 | } 2733 | #endif 2734 | if (sizeof(long) <= sizeof(long)) { 2735 | __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) 2736 | } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { 2737 | __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) 2738 | } 2739 | } 2740 | { 2741 | #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) 2742 | PyErr_SetString(PyExc_RuntimeError, 2743 | "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); 2744 | #else 2745 | long val; 2746 | PyObject *v = __Pyx_PyNumber_IntOrLong(x); 2747 | #if PY_MAJOR_VERSION < 3 2748 | if (likely(v) && !PyLong_Check(v)) { 2749 | PyObject *tmp = v; 2750 | v = PyNumber_Long(tmp); 2751 | Py_DECREF(tmp); 2752 | } 2753 | #endif 2754 | if (likely(v)) { 2755 | int one = 1; int is_little = (int)*(unsigned char *)&one; 2756 | unsigned char *bytes = (unsigned char *)&val; 2757 | int ret = _PyLong_AsByteArray((PyLongObject *)v, 2758 | bytes, sizeof(val), 2759 | is_little, !is_unsigned); 2760 | Py_DECREF(v); 2761 | if (likely(!ret)) 2762 | return val; 2763 | } 2764 | #endif 2765 | return (long) -1; 2766 | } 2767 | } else { 2768 | long val; 2769 | PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); 2770 | if (!tmp) return (long) -1; 2771 | val = __Pyx_PyInt_As_long(tmp); 2772 | Py_DECREF(tmp); 2773 | return val; 2774 | } 2775 | raise_overflow: 2776 | PyErr_SetString(PyExc_OverflowError, 2777 | "value too large to convert to long"); 2778 | return (long) -1; 2779 | raise_neg_overflow: 2780 | PyErr_SetString(PyExc_OverflowError, 2781 | "can't convert negative value to long"); 2782 | return (long) -1; 2783 | } 2784 | 2785 | /* CIntFromPy */ 2786 | static CYTHON_INLINE int __Pyx_PyInt_As_int(PyObject *x) { 2787 | const int neg_one = (int) -1, const_zero = (int) 0; 2788 | const int is_unsigned = neg_one > const_zero; 2789 | #if PY_MAJOR_VERSION < 3 2790 | if (likely(PyInt_Check(x))) { 2791 | if (sizeof(int) < sizeof(long)) { 2792 | __PYX_VERIFY_RETURN_INT(int, long, PyInt_AS_LONG(x)) 2793 | } else { 2794 | long val = PyInt_AS_LONG(x); 2795 | if (is_unsigned && unlikely(val < 0)) { 2796 | goto raise_neg_overflow; 2797 | } 2798 | return (int) val; 2799 | } 2800 | } else 2801 | #endif 2802 | if (likely(PyLong_Check(x))) { 2803 | if (is_unsigned) { 2804 | #if CYTHON_USE_PYLONG_INTERNALS 2805 | const digit* digits = ((PyLongObject*)x)->ob_digit; 2806 | switch (Py_SIZE(x)) { 2807 | case 0: return (int) 0; 2808 | case 1: __PYX_VERIFY_RETURN_INT(int, digit, digits[0]) 2809 | case 2: 2810 | if (8 * sizeof(int) > 1 * PyLong_SHIFT) { 2811 | if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { 2812 | __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2813 | } else if (8 * sizeof(int) >= 2 * PyLong_SHIFT) { 2814 | return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); 2815 | } 2816 | } 2817 | break; 2818 | case 3: 2819 | if (8 * sizeof(int) > 2 * PyLong_SHIFT) { 2820 | if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { 2821 | __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2822 | } else if (8 * sizeof(int) >= 3 * PyLong_SHIFT) { 2823 | return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); 2824 | } 2825 | } 2826 | break; 2827 | case 4: 2828 | if (8 * sizeof(int) > 3 * PyLong_SHIFT) { 2829 | if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { 2830 | __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2831 | } else if (8 * sizeof(int) >= 4 * PyLong_SHIFT) { 2832 | return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); 2833 | } 2834 | } 2835 | break; 2836 | } 2837 | #endif 2838 | #if CYTHON_COMPILING_IN_CPYTHON 2839 | if (unlikely(Py_SIZE(x) < 0)) { 2840 | goto raise_neg_overflow; 2841 | } 2842 | #else 2843 | { 2844 | int result = PyObject_RichCompareBool(x, Py_False, Py_LT); 2845 | if (unlikely(result < 0)) 2846 | return (int) -1; 2847 | if (unlikely(result == 1)) 2848 | goto raise_neg_overflow; 2849 | } 2850 | #endif 2851 | if (sizeof(int) <= sizeof(unsigned long)) { 2852 | __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) 2853 | } else if (sizeof(int) <= sizeof(unsigned PY_LONG_LONG)) { 2854 | __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) 2855 | } 2856 | } else { 2857 | #if CYTHON_USE_PYLONG_INTERNALS 2858 | const digit* digits = ((PyLongObject*)x)->ob_digit; 2859 | switch (Py_SIZE(x)) { 2860 | case 0: return (int) 0; 2861 | case -1: __PYX_VERIFY_RETURN_INT(int, sdigit, (sdigit) (-(sdigit)digits[0])) 2862 | case 1: __PYX_VERIFY_RETURN_INT(int, digit, +digits[0]) 2863 | case -2: 2864 | if (8 * sizeof(int) - 1 > 1 * PyLong_SHIFT) { 2865 | if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { 2866 | __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2867 | } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { 2868 | return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); 2869 | } 2870 | } 2871 | break; 2872 | case 2: 2873 | if (8 * sizeof(int) > 1 * PyLong_SHIFT) { 2874 | if (8 * sizeof(unsigned long) > 2 * PyLong_SHIFT) { 2875 | __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2876 | } else if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { 2877 | return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); 2878 | } 2879 | } 2880 | break; 2881 | case -3: 2882 | if (8 * sizeof(int) - 1 > 2 * PyLong_SHIFT) { 2883 | if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { 2884 | __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2885 | } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { 2886 | return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); 2887 | } 2888 | } 2889 | break; 2890 | case 3: 2891 | if (8 * sizeof(int) > 2 * PyLong_SHIFT) { 2892 | if (8 * sizeof(unsigned long) > 3 * PyLong_SHIFT) { 2893 | __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2894 | } else if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { 2895 | return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); 2896 | } 2897 | } 2898 | break; 2899 | case -4: 2900 | if (8 * sizeof(int) - 1 > 3 * PyLong_SHIFT) { 2901 | if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { 2902 | __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2903 | } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { 2904 | return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); 2905 | } 2906 | } 2907 | break; 2908 | case 4: 2909 | if (8 * sizeof(int) > 3 * PyLong_SHIFT) { 2910 | if (8 * sizeof(unsigned long) > 4 * PyLong_SHIFT) { 2911 | __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) 2912 | } else if (8 * sizeof(int) - 1 > 4 * PyLong_SHIFT) { 2913 | return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); 2914 | } 2915 | } 2916 | break; 2917 | } 2918 | #endif 2919 | if (sizeof(int) <= sizeof(long)) { 2920 | __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) 2921 | } else if (sizeof(int) <= sizeof(PY_LONG_LONG)) { 2922 | __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) 2923 | } 2924 | } 2925 | { 2926 | #if CYTHON_COMPILING_IN_PYPY && !defined(_PyLong_AsByteArray) 2927 | PyErr_SetString(PyExc_RuntimeError, 2928 | "_PyLong_AsByteArray() not available in PyPy, cannot convert large numbers"); 2929 | #else 2930 | int val; 2931 | PyObject *v = __Pyx_PyNumber_IntOrLong(x); 2932 | #if PY_MAJOR_VERSION < 3 2933 | if (likely(v) && !PyLong_Check(v)) { 2934 | PyObject *tmp = v; 2935 | v = PyNumber_Long(tmp); 2936 | Py_DECREF(tmp); 2937 | } 2938 | #endif 2939 | if (likely(v)) { 2940 | int one = 1; int is_little = (int)*(unsigned char *)&one; 2941 | unsigned char *bytes = (unsigned char *)&val; 2942 | int ret = _PyLong_AsByteArray((PyLongObject *)v, 2943 | bytes, sizeof(val), 2944 | is_little, !is_unsigned); 2945 | Py_DECREF(v); 2946 | if (likely(!ret)) 2947 | return val; 2948 | } 2949 | #endif 2950 | return (int) -1; 2951 | } 2952 | } else { 2953 | int val; 2954 | PyObject *tmp = __Pyx_PyNumber_IntOrLong(x); 2955 | if (!tmp) return (int) -1; 2956 | val = __Pyx_PyInt_As_int(tmp); 2957 | Py_DECREF(tmp); 2958 | return val; 2959 | } 2960 | raise_overflow: 2961 | PyErr_SetString(PyExc_OverflowError, 2962 | "value too large to convert to int"); 2963 | return (int) -1; 2964 | raise_neg_overflow: 2965 | PyErr_SetString(PyExc_OverflowError, 2966 | "can't convert negative value to int"); 2967 | return (int) -1; 2968 | } 2969 | 2970 | /* CheckBinaryVersion */ 2971 | static int __Pyx_check_binary_version(void) { 2972 | char ctversion[4], rtversion[4]; 2973 | PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION); 2974 | PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion()); 2975 | if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) { 2976 | char message[200]; 2977 | PyOS_snprintf(message, sizeof(message), 2978 | "compiletime version %s of module '%.100s' " 2979 | "does not match runtime version %s", 2980 | ctversion, __Pyx_MODULE_NAME, rtversion); 2981 | return PyErr_WarnEx(NULL, message, 1); 2982 | } 2983 | return 0; 2984 | } 2985 | 2986 | /* InitStrings */ 2987 | static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { 2988 | while (t->p) { 2989 | #if PY_MAJOR_VERSION < 3 2990 | if (t->is_unicode) { 2991 | *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL); 2992 | } else if (t->intern) { 2993 | *t->p = PyString_InternFromString(t->s); 2994 | } else { 2995 | *t->p = PyString_FromStringAndSize(t->s, t->n - 1); 2996 | } 2997 | #else 2998 | if (t->is_unicode | t->is_str) { 2999 | if (t->intern) { 3000 | *t->p = PyUnicode_InternFromString(t->s); 3001 | } else if (t->encoding) { 3002 | *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL); 3003 | } else { 3004 | *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1); 3005 | } 3006 | } else { 3007 | *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1); 3008 | } 3009 | #endif 3010 | if (!*t->p) 3011 | return -1; 3012 | ++t; 3013 | } 3014 | return 0; 3015 | } 3016 | 3017 | static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { 3018 | return __Pyx_PyUnicode_FromStringAndSize(c_str, (Py_ssize_t)strlen(c_str)); 3019 | } 3020 | static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) { 3021 | Py_ssize_t ignore; 3022 | return __Pyx_PyObject_AsStringAndSize(o, &ignore); 3023 | } 3024 | static CYTHON_INLINE char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { 3025 | #if CYTHON_COMPILING_IN_CPYTHON && (__PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_DEFAULT) 3026 | if ( 3027 | #if PY_MAJOR_VERSION < 3 && __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 3028 | __Pyx_sys_getdefaultencoding_not_ascii && 3029 | #endif 3030 | PyUnicode_Check(o)) { 3031 | #if PY_VERSION_HEX < 0x03030000 3032 | char* defenc_c; 3033 | PyObject* defenc = _PyUnicode_AsDefaultEncodedString(o, NULL); 3034 | if (!defenc) return NULL; 3035 | defenc_c = PyBytes_AS_STRING(defenc); 3036 | #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 3037 | { 3038 | char* end = defenc_c + PyBytes_GET_SIZE(defenc); 3039 | char* c; 3040 | for (c = defenc_c; c < end; c++) { 3041 | if ((unsigned char) (*c) >= 128) { 3042 | PyUnicode_AsASCIIString(o); 3043 | return NULL; 3044 | } 3045 | } 3046 | } 3047 | #endif 3048 | *length = PyBytes_GET_SIZE(defenc); 3049 | return defenc_c; 3050 | #else 3051 | if (__Pyx_PyUnicode_READY(o) == -1) return NULL; 3052 | #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 3053 | if (PyUnicode_IS_ASCII(o)) { 3054 | *length = PyUnicode_GET_LENGTH(o); 3055 | return PyUnicode_AsUTF8(o); 3056 | } else { 3057 | PyUnicode_AsASCIIString(o); 3058 | return NULL; 3059 | } 3060 | #else 3061 | return PyUnicode_AsUTF8AndSize(o, length); 3062 | #endif 3063 | #endif 3064 | } else 3065 | #endif 3066 | #if (!CYTHON_COMPILING_IN_PYPY) || (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE)) 3067 | if (PyByteArray_Check(o)) { 3068 | *length = PyByteArray_GET_SIZE(o); 3069 | return PyByteArray_AS_STRING(o); 3070 | } else 3071 | #endif 3072 | { 3073 | char* result; 3074 | int r = PyBytes_AsStringAndSize(o, &result, length); 3075 | if (unlikely(r < 0)) { 3076 | return NULL; 3077 | } else { 3078 | return result; 3079 | } 3080 | } 3081 | } 3082 | static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { 3083 | int is_true = x == Py_True; 3084 | if (is_true | (x == Py_False) | (x == Py_None)) return is_true; 3085 | else return PyObject_IsTrue(x); 3086 | } 3087 | static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x) { 3088 | PyNumberMethods *m; 3089 | const char *name = NULL; 3090 | PyObject *res = NULL; 3091 | #if PY_MAJOR_VERSION < 3 3092 | if (PyInt_Check(x) || PyLong_Check(x)) 3093 | #else 3094 | if (PyLong_Check(x)) 3095 | #endif 3096 | return __Pyx_NewRef(x); 3097 | m = Py_TYPE(x)->tp_as_number; 3098 | #if PY_MAJOR_VERSION < 3 3099 | if (m && m->nb_int) { 3100 | name = "int"; 3101 | res = PyNumber_Int(x); 3102 | } 3103 | else if (m && m->nb_long) { 3104 | name = "long"; 3105 | res = PyNumber_Long(x); 3106 | } 3107 | #else 3108 | if (m && m->nb_int) { 3109 | name = "int"; 3110 | res = PyNumber_Long(x); 3111 | } 3112 | #endif 3113 | if (res) { 3114 | #if PY_MAJOR_VERSION < 3 3115 | if (!PyInt_Check(res) && !PyLong_Check(res)) { 3116 | #else 3117 | if (!PyLong_Check(res)) { 3118 | #endif 3119 | PyErr_Format(PyExc_TypeError, 3120 | "__%.4s__ returned non-%.4s (type %.200s)", 3121 | name, name, Py_TYPE(res)->tp_name); 3122 | Py_DECREF(res); 3123 | return NULL; 3124 | } 3125 | } 3126 | else if (!PyErr_Occurred()) { 3127 | PyErr_SetString(PyExc_TypeError, 3128 | "an integer is required"); 3129 | } 3130 | return res; 3131 | } 3132 | static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { 3133 | Py_ssize_t ival; 3134 | PyObject *x; 3135 | #if PY_MAJOR_VERSION < 3 3136 | if (likely(PyInt_CheckExact(b))) { 3137 | if (sizeof(Py_ssize_t) >= sizeof(long)) 3138 | return PyInt_AS_LONG(b); 3139 | else 3140 | return PyInt_AsSsize_t(x); 3141 | } 3142 | #endif 3143 | if (likely(PyLong_CheckExact(b))) { 3144 | #if CYTHON_USE_PYLONG_INTERNALS 3145 | const digit* digits = ((PyLongObject*)b)->ob_digit; 3146 | const Py_ssize_t size = Py_SIZE(b); 3147 | if (likely(__Pyx_sst_abs(size) <= 1)) { 3148 | ival = likely(size) ? digits[0] : 0; 3149 | if (size == -1) ival = -ival; 3150 | return ival; 3151 | } else { 3152 | switch (size) { 3153 | case 2: 3154 | if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { 3155 | return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); 3156 | } 3157 | break; 3158 | case -2: 3159 | if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { 3160 | return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); 3161 | } 3162 | break; 3163 | case 3: 3164 | if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { 3165 | return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); 3166 | } 3167 | break; 3168 | case -3: 3169 | if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { 3170 | return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); 3171 | } 3172 | break; 3173 | case 4: 3174 | if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { 3175 | return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); 3176 | } 3177 | break; 3178 | case -4: 3179 | if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { 3180 | return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); 3181 | } 3182 | break; 3183 | } 3184 | } 3185 | #endif 3186 | return PyLong_AsSsize_t(b); 3187 | } 3188 | x = PyNumber_Index(b); 3189 | if (!x) return -1; 3190 | ival = PyInt_AsSsize_t(x); 3191 | Py_DECREF(x); 3192 | return ival; 3193 | } 3194 | static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) { 3195 | return PyInt_FromSize_t(ival); 3196 | } 3197 | 3198 | 3199 | #endif /* Py_PYTHON_H */ 3200 | --------------------------------------------------------------------------------