Merge branch 'release/3.12.1' into master

This commit is contained in:
Roman Mogylatov 2018-07-02 16:52:46 +03:00
commit 83053ad49e
27 changed files with 468 additions and 201 deletions

View File

@ -1,6 +1,7 @@
sudo: false
install:
- pip install tox
- if [[ $TRAVIS_PYTHON_VERSION == 3.3 ]]; then pip install virtualenv==15.2.0; fi
script:
- tox
language:

View File

@ -270,9 +270,9 @@ Dependency Injector in action
-----------------------------
Brief example below is a simplified version of inversion of control
containters from one of the real-life applications. This example demonstrates
usage of *Dependency Injector* inversion of control containers & providers
for specifying all application components and their dependencies beetween
container from one of the real-life applications. This example demonstrates
usage of *Dependency Injector* inversion of control container & providers
for specifying all application components and their dependencies between
each other in one module. Besides other listed above advantages, it gives a
great opportunity to control & manage application's structure in one place.
@ -285,82 +285,89 @@ great opportunity to control & manage application's structure in one place.
import boto3
import example.main
import example.services
import dependency_injector.containers as containers
import dependency_injector.providers as providers
from dependency_injector import containers, providers
from example import services, main
class Core(containers.DeclarativeContainer):
"""IoC container of core component providers."""
class IocContainer(containers.DeclarativeContainer):
"""Application IoC container."""
config = providers.Configuration('config')
logger = providers.Singleton(logging.Logger, name='example')
# Gateways
class Gateways(containers.DeclarativeContainer):
"""IoC container of gateway (API clients to remote services) providers."""
database_client = providers.Singleton(sqlite3.connect, config.database.dsn)
database = providers.Singleton(sqlite3.connect, Core.config.database.dsn)
s3 = providers.Singleton(
s3_client = providers.Singleton(
boto3.client, 's3',
aws_access_key_id=Core.config.aws.access_key_id,
aws_secret_access_key=Core.config.aws.secret_access_key)
aws_access_key_id=config.aws.access_key_id,
aws_secret_access_key=config.aws.secret_access_key
)
# Services
class Services(containers.DeclarativeContainer):
"""IoC container of business service providers."""
users_service = providers.Factory(
services.UsersService,
db=database_client,
logger=logger
)
users = providers.Factory(example.services.UsersService,
db=Gateways.database,
logger=Core.logger)
auth_service = providers.Factory(
services.AuthService,
token_ttl=config.auth.token_ttl,
db=database_client,
logger=logger
)
auth = providers.Factory(example.services.AuthService,
db=Gateways.database,
logger=Core.logger,
token_ttl=Core.config.auth.token_ttl)
photos_service = providers.Factory(
services.PhotosService,
db=database_client,
s3=s3_client,
logger=logger
)
photos = providers.Factory(example.services.PhotosService,
db=Gateways.database,
s3=Gateways.s3,
logger=Core.logger)
# Misc
class Application(containers.DeclarativeContainer):
"""IoC container of application component providers."""
main = providers.Callable(example.main.main,
users_service=Services.users,
auth_service=Services.auth,
photos_service=Services.photos)
main = providers.Callable(
main.main,
users_service=users_service,
auth_service=auth_service,
photos_service=photos_service
)
Next example demonstrates run of example application defined above:
.. code-block:: python
"""Run example application."""
"""Run example of dependency injection in Python."""
import sys
import logging
from containers import Core, Application
from container import IocContainer
if __name__ == '__main__':
# Configure platform:
Core.config.override({'database': {'dsn': ':memory:'},
'aws': {'access_key_id': 'KEY',
'secret_access_key': 'SECRET'},
'auth': {'token_ttl': 3600}})
Core.logger().addHandler(logging.StreamHandler(sys.stdout))
# Configure container:
container = IocContainer(
config={
'database': {
'dsn': ':memory:'
},
'aws': {
'access_key_id': 'KEY',
'secret_access_key': 'SECRET'
},
'auth': {
'token_ttl': 3600
}
}
)
container.logger().addHandler(logging.StreamHandler(sys.stdout))
# Run application:
Application.main(uid=sys.argv[1],
password=sys.argv[2],
photo=sys.argv[3])
container.main(*sys.argv[1:])
You can get more *Dependency Injector* examples in ``/examples`` directory on
GitHub:

View File

@ -16,6 +16,8 @@ and powered by *Dependency Injector* framework.
:maxdepth: 2
movie_lister
services_miniapp
services_miniapp_v1
services_miniapp_v2
bundles_miniapp
use_cases_miniapp
password_hashing_miniapp

View File

@ -0,0 +1,19 @@
Dependency injection and password hashing in Python
===================================================
Small example that demonstrates using of dependency injection for user
password hashing.
Instructions for running:
.. code-block:: bash
python example.py
Listing of ``example.py``:
.. literalinclude:: ../../examples/miniapps/password_hashing/example.py
:language: python
:linenos:
.. disqus::

View File

@ -1,5 +1,5 @@
Services mini application example
---------------------------------
Services mini application example (v1 - multiple containers)
------------------------------------------------------------
.. meta::
:description: "Services miniapp" is an example mini application that
@ -7,7 +7,8 @@ Services mini application example
some standard and 3rd-party libraries for logging,
interaction with database and remote service via API.
"Services miniapp" example demonstrates usage of
Dependency Injector for creating several IoC containers.
Dependency Injector for creating several inversion of control /
dependency injection containers.
"Services miniapp" is an example mini application that consists from several
services that have dependencies on some standard and 3rd-party libraries for
@ -44,13 +45,13 @@ Example application structure:
Listing of ``example/services.py``:
.. literalinclude:: ../../examples/miniapps/services/example/services.py
.. literalinclude:: ../../examples/miniapps/services_v1/example/services.py
:language: python
:linenos:
Listing of ``example/main.py``:
.. literalinclude:: ../../examples/miniapps/services/example/main.py
.. literalinclude:: ../../examples/miniapps/services_v1/example/main.py
:language: python
:linenos:
@ -59,7 +60,7 @@ IoC containers
Listing of ``containers.py``:
.. literalinclude:: ../../examples/miniapps/services/containers.py
.. literalinclude:: ../../examples/miniapps/services_v1/containers.py
:language: python
:linenos:
@ -68,7 +69,7 @@ Run application
Listing of ``run.py``:
.. literalinclude:: ../../examples/miniapps/services/run.py
.. literalinclude:: ../../examples/miniapps/services_v1/run.py
:language: python
:linenos:

View File

@ -0,0 +1,77 @@
Services mini application example (v2 - single container)
---------------------------------------------------------
.. meta::
:description: "Services miniapp" is an example mini application that
consists from several services that have dependencies on
some standard and 3rd-party libraries for logging,
interaction with database and remote service via API.
"Services miniapp" example demonstrates usage of
Dependency Injector for creating inversion of control /
dependency injection container.
"Services miniapp" is an example mini application that consists from several
services that have dependencies on some standard and 3rd-party libraries for
logging, interaction with database and remote service calls via API.
"Services miniapp" example demonstrates usage of
:doc:`Dependency Injector <../index>` for creating IoC container.
Instructions for running:
.. code-block:: bash
python run.py 1 secret photo.jpg
Example application
~~~~~~~~~~~~~~~~~~~
Classes diagram:
.. image:: /images/miniapps/services/classes.png
:width: 100%
:align: center
Example application structure:
.. code-block:: bash
/example
/__init__.py
/main.py
/services.py
Listing of ``example/services.py``:
.. literalinclude:: ../../examples/miniapps/services_v2/example/services.py
:language: python
:linenos:
Listing of ``example/main.py``:
.. literalinclude:: ../../examples/miniapps/services_v2/example/main.py
:language: python
:linenos:
IoC container
~~~~~~~~~~~~~
Listing of ``container.py``:
.. literalinclude:: ../../examples/miniapps/services_v2/container.py
:language: python
:linenos:
Run application
~~~~~~~~~~~~~~~
Listing of ``run.py``:
.. literalinclude:: ../../examples/miniapps/services_v2/run.py
:language: python
:linenos:
.. disqus::

View File

@ -7,6 +7,18 @@ that were made in every particular version.
From version 0.7.6 *Dependency Injector* framework strictly
follows `Semantic versioning`_
3.12.1
------
- Update main page example from "services_v1" to "services_v2".
- Fix few typos on main page.
- Add new example miniapp "password_hashing".
- Add new example miniapp "services_v2".
- Rename example miniapp "services" to "services_v1".
- Fix incompatibility issue between Python 3.3, pip 10.0.0 and virtualenv
16.0.0 (`details <https://github.com/awslabs/base64io-python/issues/4>`_)
that caused failures of Python 3.3 tests on Travis.
- Regenerate C sources using Cython 0.28.3.
3.12.0
------
- Regenerate C sources using Cython 0.28.2.

View File

@ -0,0 +1,12 @@
Dependency injection and password hashing in Python
===================================================
Small example that demonstrates using of dependency injection for user
password hashing.
instructions for running:
.. code-block:: bash
python example.py

View File

@ -0,0 +1,42 @@
"""Example of dependency injection and password hashing in Python."""
import passlib.hash
import dependency_injector.containers as containers
import dependency_injector.providers as providers
class UsersService(object):
"""Users service."""
def __init__(self, password_hasher):
"""Initializer."""
self._password_hasher = password_hasher
def create_user(self, name, password):
"""Create user with hashed password."""
hashed_password = self._password_hasher(password)
return dict(name=name, password=hashed_password)
class Container(containers.DeclarativeContainer):
"""Inversion of control container."""
password_hasher = providers.Callable(
passlib.hash.sha256_crypt.encrypt,
salt_size=16,
rounds=10000)
users_service = providers.Factory(
UsersService,
password_hasher=password_hasher.provider)
if __name__ == '__main__':
container = Container()
users_service = container.users_service()
user1 = users_service.create_user(name='Roman', password='secret1')
user2 = users_service.create_user(name='Vitaly', password='secret2')
print(user1, user2)

View File

@ -1,27 +0,0 @@
"""Example main module."""
def main(uid, password, photo, users_service, auth_service, photos_service):
"""Authenticate user and upload photo.
:param uid: User identifier.
:type uid: int
:param password: User's password for verification.
:type password: str
:param photo_path: Path to photo for uploading.
:type photo_path: str
:param users_service: Users service.
:type users_service: example.services.UsersService
:param auth_service: Authentication service.
:type auth_service: example.services.AuthService
:param photo_service: Photo service.
:type photo_service: example.services.PhotoService
"""
user = users_service.get_user_by_id(uid)
auth_service.authenticate(user, password)
photos_service.upload_photo(user['uid'], photo)

View File

@ -1,103 +0,0 @@
"""Example business services module."""
class BaseService(object):
"""Service base class."""
class UsersService(BaseService):
"""Users service."""
def __init__(self, logger, db):
"""Initializer.
:param logger: Logger instance.
:type logger: logging.Logger
:param db: Database connection.
:type db: sqlite3.Connection
"""
self.logger = logger
self.db = db
def get_user_by_id(self, uid):
"""Return user's data by identifier.
:param uid: User identifier.
:type uid: int
:rtype: dict
"""
self.logger.debug('User %s has been found in database', uid)
return dict(uid=uid, password_hash='secret_hash')
class AuthService(BaseService):
"""Authentication service."""
def __init__(self, logger, db, token_ttl):
"""Initializer.
:param logger: Logger instance.
:type logger: logging.Logger
:param db: Database connection.
:type db: sqlite3.Connection
:param token_ttl: Token lifetime in seconds.
:type token_ttl: int
"""
self.logger = logger
self.db = db
self.token_ttl = token_ttl
def authenticate(self, user, password):
"""Authenticate user.
:param user: User's data.
:type user: dict
:param password: User's password for verification.
:type password: str
:raises: AssertionError when password is wrong
:rtype: None
"""
assert user['password_hash'] == '_'.join((password, 'hash'))
self.logger.debug('User %s has been successfully authenticated',
user['uid'])
class PhotosService(BaseService):
"""Photos service."""
def __init__(self, logger, db, s3):
"""Initializer.
:param logger: Logger instance.
:type logger: logging.Logger
:param db: Database connection.
:type db: sqlite3.Connection
:param s3: AWS S3 client.
:type s3: botocore.client.S3
"""
self.logger = logger
self.db = db
self.s3 = s3
def upload_photo(self, uid, photo_path):
"""Upload user photo.
:param uid: User identifier.
:type uid: int
:param photo_path: Path to photo for uploading.
:type photo_path: str
:rtpe: None
"""
self.logger.debug('Photo %s has been successfully uploaded by user %s',
photo_path, uid)

View File

@ -0,0 +1,8 @@
"""Example main module."""
def main(uid, password, photo, users_service, auth_service, photos_service):
"""Authenticate user and upload photo."""
user = users_service.get_user_by_id(uid)
auth_service.authenticate(user, password)
photos_service.upload_photo(user['uid'], photo)

View File

@ -0,0 +1,50 @@
"""Example business services module."""
class BaseService(object):
"""Service base class."""
class UsersService(BaseService):
"""Users service."""
def __init__(self, logger, db):
"""Initializer."""
self.logger = logger
self.db = db
def get_user_by_id(self, uid):
"""Return user's data by identifier."""
self.logger.debug('User %s has been found in database', uid)
return dict(uid=uid, password_hash='secret_hash')
class AuthService(BaseService):
"""Authentication service."""
def __init__(self, logger, db, token_ttl):
"""Initializer."""
self.logger = logger
self.db = db
self.token_ttl = token_ttl
def authenticate(self, user, password):
"""Authenticate user."""
assert user['password_hash'] == '_'.join((password, 'hash'))
self.logger.debug('User %s has been successfully authenticated',
user['uid'])
class PhotosService(BaseService):
"""Photos service."""
def __init__(self, logger, db, s3):
"""Initializer."""
self.logger = logger
self.db = db
self.s3 = s3
def upload_photo(self, uid, photo_path):
"""Upload user photo."""
self.logger.debug('Photo %s has been successfully uploaded by user %s',
photo_path, uid)

View File

@ -0,0 +1,8 @@
Dependency Injector IoC containers example
==========================================
Instructions for running
.. code-block:: bash
python run.py 1 secret photo.jpg

View File

@ -0,0 +1,57 @@
"""Example of dependency injection in Python."""
import logging
import sqlite3
import boto3
from dependency_injector import containers, providers
from example import services, main
class IocContainer(containers.DeclarativeContainer):
"""Application IoC container."""
config = providers.Configuration('config')
logger = providers.Singleton(logging.Logger, name='example')
# Gateways
database_client = providers.Singleton(sqlite3.connect, config.database.dsn)
s3_client = providers.Singleton(
boto3.client, 's3',
aws_access_key_id=config.aws.access_key_id,
aws_secret_access_key=config.aws.secret_access_key
)
# Services
users_service = providers.Factory(
services.UsersService,
db=database_client,
logger=logger
)
auth_service = providers.Factory(
services.AuthService,
token_ttl=config.auth.token_ttl,
db=database_client,
logger=logger
)
photos_service = providers.Factory(
services.PhotosService,
db=database_client,
s3=s3_client,
logger=logger
)
# Misc
main = providers.Callable(
main.main,
users_service=users_service,
auth_service=auth_service,
photos_service=photos_service
)

View File

@ -0,0 +1 @@
"""Example top-level package."""

View File

@ -0,0 +1,8 @@
"""Example main module."""
def main(uid, password, photo, users_service, auth_service, photos_service):
"""Authenticate user and upload photo."""
user = users_service.get_user_by_id(uid)
auth_service.authenticate(user, password)
photos_service.upload_photo(user['uid'], photo)

View File

@ -0,0 +1,50 @@
"""Example business services module."""
class BaseService(object):
"""Service base class."""
class UsersService(BaseService):
"""Users service."""
def __init__(self, logger, db):
"""Initializer."""
self.logger = logger
self.db = db
def get_user_by_id(self, uid):
"""Return user's data by identifier."""
self.logger.debug('User %s has been found in database', uid)
return dict(uid=uid, password_hash='secret_hash')
class AuthService(BaseService):
"""Authentication service."""
def __init__(self, logger, db, token_ttl):
"""Initializer."""
self.logger = logger
self.db = db
self.token_ttl = token_ttl
def authenticate(self, user, password):
"""Authenticate user."""
assert user['password_hash'] == '_'.join((password, 'hash'))
self.logger.debug('User %s has been successfully authenticated',
user['uid'])
class PhotosService(BaseService):
"""Photos service."""
def __init__(self, logger, db, s3):
"""Initializer."""
self.logger = logger
self.db = db
self.s3 = s3
def upload_photo(self, uid, photo_path):
"""Upload user photo."""
self.logger.debug('Photo %s has been successfully uploaded by user %s',
photo_path, uid)

View File

@ -0,0 +1,28 @@
"""Run example of dependency injection in Python."""
import sys
import logging
from container import IocContainer
if __name__ == '__main__':
# Configure container:
container = IocContainer(
config={
'database': {
'dsn': ':memory:'
},
'aws': {
'access_key_id': 'KEY',
'secret_access_key': 'SECRET'
},
'auth': {
'token_ttl': 3600
}
}
)
container.logger().addHandler(logging.StreamHandler(sys.stdout))
# Run application:
container.main(*sys.argv[1:])

View File

@ -1,4 +1,4 @@
cython==0.27.3
cython==0.28.3
tox
unittest2
coverage

View File

@ -1,6 +1,6 @@
"""Dependency injector top-level package."""
__version__ = '3.12.0'
__version__ = '3.12.1'
"""Version number that follows semantic versioning.
:type: str

View File

@ -1,4 +1,4 @@
/* Generated by Cython 0.28.2 */
/* Generated by Cython 0.28.3 */
#define PY_SSIZE_T_CLEAN
#include "Python.h"
@ -7,7 +7,7 @@
#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
#error Cython requires Python 2.6+ or Python 3.3+.
#else
#define CYTHON_ABI "0_28_2"
#define CYTHON_ABI "0_28_3"
#define CYTHON_FUTURE_DIVISION 0
#include <stddef.h>
#ifndef offsetof
@ -453,6 +453,7 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
#define PyString_Type PyUnicode_Type
#define PyString_Check PyUnicode_Check
#define PyString_CheckExact PyUnicode_CheckExact
#define PyObject_Unicode PyObject_Str
#endif
#if PY_MAJOR_VERSION >= 3
#define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
@ -645,7 +646,7 @@ static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) {
#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj)
#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None)
#define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False))
static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b);
static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x);
#define __Pyx_PySequence_Tuple(obj)\
@ -753,7 +754,7 @@ static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; }
static PyObject *__pyx_m = NULL;
static PyObject *__pyx_d;
static PyObject *__pyx_b;
static PyObject *__pyx_cython_runtime;
static PyObject *__pyx_cython_runtime = NULL;
static PyObject *__pyx_empty_tuple;
static PyObject *__pyx_empty_bytes;
static PyObject *__pyx_empty_unicode;
@ -11455,7 +11456,7 @@ static int __Pyx_modinit_function_import_code(void) {
#ifndef CYTHON_SMALL_CODE
#if defined(__clang__)
#define CYTHON_SMALL_CODE
#elif defined(__GNUC__)
#elif defined(__GNUC__) && (!(defined(__cplusplus)) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)))
#define CYTHON_SMALL_CODE __attribute__((optimize("Os")))
#else
#define CYTHON_SMALL_CODE
@ -14131,6 +14132,9 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li
#if CYTHON_COMPILING_IN_CPYTHON
PyObject **cython_runtime_dict;
#endif
if (unlikely(!__pyx_cython_runtime)) {
return c_line;
}
__Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback);
#if CYTHON_COMPILING_IN_CPYTHON
cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime);
@ -16325,6 +16329,9 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
Py_DECREF(x);
return ival;
}
static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) {
return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False);
}
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
return PyInt_FromSize_t(ival);
}

View File

@ -1,4 +1,4 @@
/* Generated by Cython 0.28.2 */
/* Generated by Cython 0.28.3 */
#define PY_SSIZE_T_CLEAN
#include "Python.h"
@ -7,7 +7,7 @@
#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
#error Cython requires Python 2.6+ or Python 3.3+.
#else
#define CYTHON_ABI "0_28_2"
#define CYTHON_ABI "0_28_3"
#define CYTHON_FUTURE_DIVISION 0
#include <stddef.h>
#ifndef offsetof
@ -453,6 +453,7 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
#define PyString_Type PyUnicode_Type
#define PyString_Check PyUnicode_Check
#define PyString_CheckExact PyUnicode_CheckExact
#define PyObject_Unicode PyObject_Str
#endif
#if PY_MAJOR_VERSION >= 3
#define __Pyx_PyBaseString_Check(obj) PyUnicode_Check(obj)
@ -645,7 +646,7 @@ static CYTHON_INLINE size_t __Pyx_Py_UNICODE_strlen(const Py_UNICODE *u) {
#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode
#define __Pyx_NewRef(obj) (Py_INCREF(obj), obj)
#define __Pyx_Owned_Py_None(b) __Pyx_NewRef(Py_None)
#define __Pyx_PyBool_FromLong(b) ((b) ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False))
static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b);
static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x);
#define __Pyx_PySequence_Tuple(obj)\
@ -753,7 +754,7 @@ static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; }
static PyObject *__pyx_m = NULL;
static PyObject *__pyx_d;
static PyObject *__pyx_b;
static PyObject *__pyx_cython_runtime;
static PyObject *__pyx_cython_runtime = NULL;
static PyObject *__pyx_empty_tuple;
static PyObject *__pyx_empty_bytes;
static PyObject *__pyx_empty_unicode;
@ -56515,7 +56516,7 @@ static int __Pyx_modinit_function_import_code(void) {
#ifndef CYTHON_SMALL_CODE
#if defined(__clang__)
#define CYTHON_SMALL_CODE
#elif defined(__GNUC__)
#elif defined(__GNUC__) && (!(defined(__cplusplus)) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)))
#define CYTHON_SMALL_CODE __attribute__((optimize("Os")))
#else
#define CYTHON_SMALL_CODE
@ -59958,6 +59959,9 @@ static int __Pyx_CLineForTraceback(CYTHON_UNUSED PyThreadState *tstate, int c_li
#if CYTHON_COMPILING_IN_CPYTHON
PyObject **cython_runtime_dict;
#endif
if (unlikely(!__pyx_cython_runtime)) {
return c_line;
}
__Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback);
#if CYTHON_COMPILING_IN_CPYTHON
cython_runtime_dict = _PyObject_GetDictPtr(__pyx_cython_runtime);
@ -60939,6 +60943,9 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
Py_DECREF(x);
return ival;
}
static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) {
return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False);
}
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
return PyInt_FromSize_t(ival);
}