:class:`._Dispatch` objects.
"""
- if "_joined_dispatch_cls" not in self.__class__.__dict__:
- cls = type(
- "Joined%s" % self.__class__.__name__,
- (_JoinedDispatcher,),
- {"__slots__": self._event_names},
- )
- self.__class__._joined_dispatch_cls = cls
-
- # establish pickle capability by adding it to this module
- globals()[cls.__name__] = cls
+ assert "_joined_dispatch_cls" in self.__class__.__dict__
return self._joined_dispatch_cls(self, other)
else:
dispatch_target_cls.dispatch = dispatcher(cls)
+ klass = type(
+ "Joined%s" % dispatch_cls.__name__,
+ (_JoinedDispatcher,),
+ {"__slots__": event_names},
+ )
+ dispatch_cls._joined_dispatch_cls = klass
+
+ # establish pickle capability by adding it to this module
+ globals()[klass.__name__] = klass
+
+
+class _JoinedDispatcher(_DispatchCommon[_ET]):
+ """Represent a connection between two _Dispatch objects."""
+
+ __slots__ = "local", "parent", "_instance_cls"
+
+ local: _DispatchCommon[_ET]
+ parent: _DispatchCommon[_ET]
+ _instance_cls: Optional[Type[_ET]]
+
+ def __init__(
+ self, local: _DispatchCommon[_ET], parent: _DispatchCommon[_ET]
+ ):
+ self.local = local
+ self.parent = parent
+ self._instance_cls = self.local._instance_cls
+
+ def __reduce__(self) -> Any:
+ return (self.__class__, (self.local, self.parent))
+
+ def __getattr__(self, name: str) -> _JoinedListener[_ET]:
+ # Assign _JoinedListeners as attributes on demand
+ # to reduce startup time for new dispatch objects.
+ ls = getattr(self.local, name)
+ jl = _JoinedListener(self.parent, ls.name, ls)
+ setattr(self, ls.name, jl)
+ return jl
+
+ def _listen(self, event_key: _EventKey[_ET], **kw: Any) -> None:
+ return self.parent._listen(event_key, **kw)
+
+ @property
+ def _events(self) -> Type[_HasEventsDispatch[_ET]]:
+ return self.parent._events
+
class Events(_HasEventsDispatch[_ET]):
"""Define event listening functions for a particular target type."""
cls.dispatch._clear()
-class _JoinedDispatcher(_DispatchCommon[_ET]):
- """Represent a connection between two _Dispatch objects."""
-
- __slots__ = "local", "parent", "_instance_cls"
-
- local: _DispatchCommon[_ET]
- parent: _DispatchCommon[_ET]
- _instance_cls: Optional[Type[_ET]]
-
- def __init__(
- self, local: _DispatchCommon[_ET], parent: _DispatchCommon[_ET]
- ):
- self.local = local
- self.parent = parent
- self._instance_cls = self.local._instance_cls
-
- def __reduce__(self) -> Any:
- return (self.__class__, (self.local, self.parent))
-
- def __getattr__(self, name: str) -> _JoinedListener[_ET]:
- # Assign _JoinedListeners as attributes on demand
- # to reduce startup time for new dispatch objects.
- ls = getattr(self.local, name)
- jl = _JoinedListener(self.parent, ls.name, ls)
- setattr(self, ls.name, jl)
- return jl
-
- def _listen(self, event_key: _EventKey[_ET], **kw: Any) -> None:
- return self.parent._listen(event_key, **kw)
-
- @property
- def _events(self) -> Type[_HasEventsDispatch[_ET]]:
- return self.parent._events
-
-
class dispatcher(Generic[_ET]):
"""Descriptor used by target classes to
deliver the _Dispatch class at the class level
import importlib
import operator
import os
+import pickle
+import subprocess
+import sys
+from tempfile import mkstemp
import sqlalchemy as sa
from sqlalchemy import and_
loads(dumps(column_type))
loads(dumps(meta))
+ @testing.combinations(
+ ("Str", String()),
+ ("Tex", Text()),
+ ("Uni", Unicode()),
+ ("Boo", Boolean()),
+ ("Dat", DateTime()),
+ ("Dat", Date()),
+ ("Tim", Time()),
+ ("Lar", LargeBinary()),
+ ("Pic", PickleType()),
+ ("Int", Interval()),
+ ("Enu", Enum("one", "two", "three")),
+ argnames="name,type_",
+ id_="ar",
+ )
+ @testing.variation("use_adapt", [True, False])
+ def test_pickle_types_other_process(self, name, type_, use_adapt):
+ """test for #11530
+
+ this does a full exec of python interpreter so the number of variations
+ here is reduced to just a single pickler, else each case takes
+ a full second.
+
+ """
+
+ if use_adapt:
+ type_ = type_.copy()
+
+ column_type = Column(name, type_)
+ meta = MetaData()
+ Table("foo", meta, column_type)
+
+ for target in column_type, meta:
+ f, name = mkstemp("pkl")
+ with os.fdopen(f, "wb") as f:
+ pickle.dump(target, f)
+
+ name = name.replace(os.sep, "/")
+ code = (
+ "import sqlalchemy; import pickle; "
+ f"pickle.load(open('''{name}''', 'rb'))"
+ )
+ parts = list(sys.path)
+ if os.environ.get("PYTHONPATH"):
+ parts.append(os.environ["PYTHONPATH"])
+ pythonpath = os.pathsep.join(parts)
+ proc = subprocess.run(
+ [sys.executable, "-c", code],
+ env={**os.environ, "PYTHONPATH": pythonpath},
+ )
+ eq_(proc.returncode, 0)
+ os.unlink(name)
+
class _UserDefinedTypeFixture:
@classmethod