Skip to content

Commit 55e6f59

Browse files
committed
Refactor ContextMeta.
Per @lucianopaz, move the installation of `__enter__` and `__exit__` methods from `__init__()` to `__new__()`.
1 parent 08d7e12 commit 55e6f59

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

pymc3/model.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -169,36 +169,38 @@ class ContextMeta(type):
169169
the `with` statement.
170170
"""
171171

172-
def __new__(cls, name, bases, dct, **kargs):
173-
# this serves only to strip off keyword args, per the warning from
174-
# StackExchange:
175-
# DO NOT send "**kargs" to "type.__new__". It won't catch them and
176-
# you'll get a "TypeError: type() takes 1 or 3 arguments" exception.
177-
return super().__new__(cls, name, bases, dct)
178-
179-
# FIXME: is there a more elegant way to automatically add methods to the class that
180-
# are instance methods instead of class methods?
181-
def __init__(cls, name, bases, nmspc, context_class: Optional[Type]=None, **kwargs): # pylint: disable=unused-variable
182-
"""Add ``__enter__`` and ``__exit__`` methods to the new class automatically."""
183-
if context_class is not None:
184-
cls._context_class = context_class
185-
super().__init__(name, bases, nmspc)
186-
172+
def __new__(cls, name, bases, dct, **kargs): # pylint: disable=unused-argument
173+
"Add __enter__ and __exit__ methods to the class."
187174
def __enter__(self):
188175
self.__class__.context_class.get_contexts().append(self)
189176
# self._theano_config is set in Model.__new__
190177
if hasattr(self, '_theano_config'):
191178
self._old_theano_config = set_theano_conf(self._theano_config)
192179
return self
193180

194-
def __exit__(self, typ, value, traceback): # pylint: disable=unused-variable
181+
def __exit__(self, typ, value, traceback): # pylint: disable=unused-argument
195182
self.__class__.context_class.get_contexts().pop()
196183
# self._theano_config is set in Model.__new__
197184
if hasattr(self, '_old_theano_config'):
198185
set_theano_conf(self._old_theano_config)
199186

200-
cls.__enter__ = __enter__
201-
cls.__exit__ = __exit__
187+
dct[__enter__.__name__] = __enter__
188+
dct[__exit__.__name__] = __exit__
189+
190+
# We strip off keyword args, per the warning from
191+
# StackExchange:
192+
# DO NOT send "**kargs" to "type.__new__". It won't catch them and
193+
# you'll get a "TypeError: type() takes 1 or 3 arguments" exception.
194+
return super().__new__(cls, name, bases, dct)
195+
196+
# FIXME: is there a more elegant way to automatically add methods to the class that
197+
# are instance methods instead of class methods?
198+
def __init__(cls, name, bases, nmspc, context_class: Optional[Type]=None, **kwargs): # pylint: disable=unused-argument
199+
"""Add ``__enter__`` and ``__exit__`` methods to the new class automatically."""
200+
if context_class is not None:
201+
cls._context_class = context_class
202+
super().__init__(name, bases, nmspc)
203+
202204

203205

204206
def get_context(cls, error_if_none=True) -> Optional[T]:

0 commit comments

Comments
 (0)