Skip to content

Commit

Permalink
Docs for singleton.py
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed Jul 19, 2018
1 parent 3394fae commit cde8057
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
42 changes: 41 additions & 1 deletion src/nti/externalization/singleton.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
# cython: auto_pickle=False,embedsignature=True,always_allow_keywords=False
# -*- coding: utf-8 -*-
"""
Support for singleton objects that are used as external object decorators.
Support for fast, memory efficient singleton objects.
Why is this here? The externalization system can use lots of objects
as it goes through its process. Many of those objects are adapters
(for example, the decorator objectes), meaning a factory callable is
called to (create and) return an object (given a particular context,
and possibly request).
But the API of many adapter objects accept all the information they
need to have in the functions defined in the interface. That is, the
constructor does nothing useful with the context (and request). The
objects are stateless, and so constructing a new one for each adapter
invocation can be a waste of time and memory.
By either using the `SingletonMetaclass` as your metaclass, or
subclassing `Singleton`, that cost is paid only once, replacing a call
to a constructor and an object allocation with a faster call to return
a constant object.
"""

from __future__ import absolute_import
Expand All @@ -10,6 +27,11 @@

# This was originally based on code from sympy.core.singleton

__all__ = [
'SingletonMetaclass',
'Singleton',
]

class SingletonMetaclass(type):
"""
Metaclass for singleton classes most commonly used as external object
Expand Down Expand Up @@ -39,6 +61,24 @@ class is instantiated.
The original constructor is also cached to allow subclasses to access it
and have their own instance.
>>> class TopSingleton(Singleton):
... def __init__(self):
... print("I am never called")
>>> inst = TopSingleton()
>>> isinstance(inst, TopSingleton)
True
>>> TopSingleton() is inst
True
>>> class DerivedSingelton(TopSingleton):
... pass
>>> derived = DerivedSingelton()
>>> isinstance(derived, DerivedSingelton)
True
>>> DerivedSingelton() is derived
True
>>> derived is inst
False
"""

def __new__(mcs, name, bases, cls_dict):
Expand Down
14 changes: 14 additions & 0 deletions src/nti/externalization/tests/test_singleton.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from __future__ import division
from __future__ import print_function


from nti.externalization.singleton import SingletonDecorator
from nti.externalization.tests import ExternalizationLayerTest

Expand Down Expand Up @@ -53,3 +54,16 @@ class Z(Y):
assert_that(Z(), is_(same_instance(Z())))
assert_that(X(), is_not(same_instance(Z())))
assert_that(Y(), is_not(same_instance(Z())))


def test_suite():
import unittest
import doctest
suite = unittest.defaultTestLoader.loadTestsFromName(__name__)

return unittest.TestSuite([
suite,
doctest.DocTestSuite(
'nti.externalization.singleton',
),
])

0 comments on commit cde8057

Please sign in to comment.