vortexpy 4.0.28__tar.gz → 4.0.29__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. {vortexpy-4.0.28/vortexpy.egg-info → vortexpy-4.0.29}/PKG-INFO +2 -24
  2. {vortexpy-4.0.28 → vortexpy-4.0.29}/pyproject.toml +2 -2
  3. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/PayloadEndpoint.py +1 -1
  4. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/PayloadEndpointTest.py +60 -49
  5. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexFactory.py +8 -2
  6. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/__init__.py +1 -1
  7. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/event_bus/TupleChangeEventBus.py +23 -0
  8. {vortexpy-4.0.28 → vortexpy-4.0.29/vortexpy.egg-info}/PKG-INFO +2 -24
  9. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortexpy.egg-info/SOURCES.txt +0 -1
  10. vortexpy-4.0.28/LICENSE +0 -22
  11. {vortexpy-4.0.28 → vortexpy-4.0.29}/README.md +0 -0
  12. {vortexpy-4.0.28 → vortexpy-4.0.29}/setup.cfg +0 -0
  13. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/DataWrapTuple.py +0 -0
  14. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/DeferUtil.py +0 -0
  15. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/Jsonable.py +0 -0
  16. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/Payload.py +0 -0
  17. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/PayloadEnvelope.py +0 -0
  18. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/PayloadFilterKeys.py +0 -0
  19. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/PayloadIO.py +0 -0
  20. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/PayloadPriority.py +0 -0
  21. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/PayloadResponse.py +0 -0
  22. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/PayloadResponseTest.py +0 -0
  23. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/PayloadTest.py +0 -0
  24. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/PerformTestActionTuple.py +0 -0
  25. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/SerialiseUtil.py +0 -0
  26. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/TestTuple.py +0 -0
  27. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/Tuple.py +0 -0
  28. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/TupleAction.py +0 -0
  29. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/TupleDataForTest.py +0 -0
  30. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/TuplePerfTest.py +0 -0
  31. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/TuplePolymorphicTupleTypeFieldArgTest.py +0 -0
  32. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/TupleRestful.py +0 -0
  33. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/TupleRestfulTest.py +0 -0
  34. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/TupleSelector.py +0 -0
  35. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/TupleTest.py +0 -0
  36. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexABC.py +0 -0
  37. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexAccessControlContextABC.py +0 -0
  38. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexAuthenticatorABC.py +0 -0
  39. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexClientHttp.py +0 -0
  40. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexClientHttpTest.py +0 -0
  41. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexClientTcp.py +0 -0
  42. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexClientWebsocketFactory.py +0 -0
  43. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexConnectionABC.py +0 -0
  44. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexEndpointPermission.py +0 -0
  45. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexPayloadProtocol.py +0 -0
  46. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexPermission.py +0 -0
  47. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexPermissionError.py +0 -0
  48. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexServer.py +0 -0
  49. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexServerConnection.py +0 -0
  50. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexServerHttpResource.py +0 -0
  51. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexServerTcp.py +0 -0
  52. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexServerWebsocket.py +0 -0
  53. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexSession.py +0 -0
  54. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexTcpMemoryLeakPayloadTest.py +0 -0
  55. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexTcpMemoryLeakRawTest.py +0 -0
  56. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexTest.py +0 -0
  57. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexUtil.py +0 -0
  58. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/VortexWritePushProducer.py +0 -0
  59. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/data_loader/TupleDataLiveLockManager.py +0 -0
  60. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/data_loader/TupleDataLoader.py +0 -0
  61. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/data_loader/TupleDataLoaderDelegate.py +0 -0
  62. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/data_loader/TupleDataLoaderTupleABC.py +0 -0
  63. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/data_loader/TupleDataLoaderTuples.py +0 -0
  64. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/data_loader/__init__.py +0 -0
  65. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/event_bus/TupleChangeEventABC.py +0 -0
  66. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/event_bus/TupleChangeEventBusObserverABC.py +0 -0
  67. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/event_bus/__init__.py +0 -0
  68. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/TupleActionProcessor.py +0 -0
  69. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/TupleActionProcessorProxy.py +0 -0
  70. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/TupleActionProcessorTestHandler.py +0 -0
  71. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/TupleDataAccessGranterABC.py +0 -0
  72. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/TupleDataActionClient.py +0 -0
  73. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/TupleDataObservableCache.py +0 -0
  74. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/TupleDataObservableHandler.py +0 -0
  75. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/TupleDataObservableProxyHandler.py +0 -0
  76. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/TupleDataObservableTestHandler.py +0 -0
  77. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/TupleDataObserverClient.py +0 -0
  78. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/TupleDataProviderABC.py +0 -0
  79. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/VortexJSTupleLoaderTestHandler.py +0 -0
  80. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/handler/__init__.py +0 -0
  81. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/mypy_plugin.py +0 -0
  82. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/py.typed +0 -0
  83. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/restful/GzippedDataHttpClient.py +0 -0
  84. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/restful/GzippedDataHttpClientTest.py +0 -0
  85. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/restful/GzippedPayloadHttpClient.py +0 -0
  86. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/restful/RestfulHttpClient.py +0 -0
  87. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/restful/RestfulHttpClientTest.py +0 -0
  88. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/restful/RestfulResource.py +0 -0
  89. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/restful/RestfulResourceTest.py +0 -0
  90. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/restful/__init__.py +0 -0
  91. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/rpc/RPC.py +0 -0
  92. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/rpc/RPCTest.py +0 -0
  93. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/rpc/__init__.py +0 -0
  94. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/sqla_orm/OrmCrudHandler.py +0 -0
  95. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/sqla_orm/TupleProviderForDb.py +0 -0
  96. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/sqla_orm/VortexTupleJson.py +0 -0
  97. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/sqla_orm/__init__.py +0 -0
  98. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/storage/TupleStorageSqlite.py +0 -0
  99. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortex/storage/__init__.py +0 -0
  100. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortexpy.egg-info/dependency_links.txt +0 -0
  101. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortexpy.egg-info/entry_points.txt +0 -0
  102. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortexpy.egg-info/requires.txt +0 -0
  103. {vortexpy-4.0.28 → vortexpy-4.0.29}/vortexpy.egg-info/top_level.txt +0 -0
@@ -1,31 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vortexpy
3
- Version: 4.0.28
3
+ Version: 4.0.29
4
4
  Summary: Flying Ion's observable, routable, data serialisation and transport code.
5
5
  Author-email: Flying Ion Pty Ltd <contact@flyingion.com>
6
- License: MIT License
7
-
8
- Copyright (c) 2016-2026 Flying Ion Pty Ltd
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a copy
11
- of this software and associated documentation files (the "Software"), to deal
12
- in the Software without restriction, including without limitation the rights
13
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
- copies of the Software, and to permit persons to whom the Software is
15
- furnished to do so, subject to the following conditions:
16
-
17
- The above copyright notice and this permission notice shall be included in all
18
- copies or substantial portions of the Software.
19
-
20
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
- SOFTWARE.
27
-
28
-
6
+ License: MIT
29
7
  Project-URL: Homepage, https://flyingion.com
30
8
  Project-URL: Repository, https://gitlab.com/flyingion/vortexpy
31
9
  Project-URL: Issues, https://gitlab.com/flyingion/vortexpy/-/issues
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "vortexpy"
7
- version = "4.0.28"
8
- license = {file = "LICENSE"}
7
+ version = "4.0.29"
8
+ license = {text = "MIT"}
9
9
  authors = [{name = "Flying Ion Pty Ltd", email = "contact@flyingion.com"}]
10
10
  description = "Flying Ion's observable, routable, data serialisation and transport code."
11
11
  readme = "README.md"
@@ -274,7 +274,7 @@ class PayloadEndpoint:
274
274
  )
275
275
  if self._callableAcceptsAccessControlContext:
276
276
  kwargs["accessControlContext"] = accessControlContext
277
- return callable_(**kwargs)
277
+ return (yield maybeDeferred(callable_, **kwargs))
278
278
  else:
279
279
  PayloadIO().remove(self)
280
280
 
@@ -6,6 +6,9 @@
6
6
  # Website : https://flyingion.com
7
7
  # Support : contact@flyingion.com
8
8
 
9
+ from twisted.internet import reactor
10
+ from twisted.internet.defer import Deferred
11
+ from twisted.internet.defer import inlineCallbacks
9
12
  from twisted.trial import unittest
10
13
 
11
14
  from vortex.Payload import Payload
@@ -19,7 +22,7 @@ class PayloadEndpointPyTestAssignPayload:
19
22
  self._ut = unitTest
20
23
 
21
24
  def process(self, payloadEnvelope: PayloadEnvelope, **kwargs):
22
- self._ut.deliveredPayload = payloadEnvelope
25
+ self._ut.deliveredPayloadEnvelope = payloadEnvelope
23
26
 
24
27
 
25
28
  class PayloadEndpointPyTest(unittest.TestCase):
@@ -28,46 +31,66 @@ class PayloadEndpointPyTest(unittest.TestCase):
28
31
 
29
32
  self.deliveredPayloadEnvelope = None
30
33
 
31
- def _testBuild(self, plFilt, epFilt):
34
+ @inlineCallbacks
35
+ def _flushReactor(self):
36
+ # PayloadIO schedules via callLater(0); PayloadEndpoint.process yields
37
+ # maybeDeferred — allow a few reactor turns to finish delivery.
38
+ for _ in range(3):
39
+ d = Deferred()
40
+ reactor.callLater(0, d.callback, None)
41
+ yield d
42
+
43
+ def _newPayload(self, plFilt: dict) -> Payload:
32
44
  payload = Payload()
33
45
  payload.filt.update(plFilt)
34
46
  for x in range(6):
35
47
  payload.filt["%s" % x] = x
48
+ return payload
36
49
 
37
- def processPayload(payloadEnvelope: PayloadEnvelope, **kwargs):
38
- self.deliveredPayloadEnvelope = payloadEnvelope
39
-
40
- self._keepFuncInScope = processPayload
41
-
42
- PayloadEndpoint(epFilt, processPayload, requiredPermissions=frozenset())
43
-
50
+ def _processEnvelope(self, payload: Payload) -> None:
51
+ # Build envelope without Payload.makePayloadEnvelope() — that path
52
+ # forbids the reactor thread (blocking encode).
44
53
  PayloadIO().process(
45
- payloadEnvelope=payload.makePayloadEnvelope(),
54
+ payloadEnvelope=PayloadEnvelope(filt=payload.filt),
46
55
  vortexUuid="test",
47
56
  vortexName="test",
48
57
  vortexSession=None,
49
58
  sendResponse=lambda x: x,
50
59
  )
51
60
 
61
+ def _registerAndProcess(self, plFilt, epFilt) -> Payload:
62
+ payload = self._newPayload(plFilt)
63
+
64
+ def processPayload(payloadEnvelope: PayloadEnvelope, **kwargs):
65
+ self.deliveredPayloadEnvelope = payloadEnvelope
66
+
67
+ self._keepFuncInScope = processPayload
68
+
69
+ PayloadEndpoint(epFilt, processPayload, requiredPermissions=frozenset())
70
+ self._processEnvelope(payload)
52
71
  return payload
53
72
 
73
+ @inlineCallbacks
54
74
  def testFiltMatches(self):
55
75
  plFilt = {"key": "unittest", "This matches": 555}
56
76
  epFilt = {"key": "unittest", "This matches": 555}
57
77
 
58
- payload = self._testBuild(plFilt, epFilt)
78
+ payload = self._registerAndProcess(plFilt, epFilt)
79
+ yield self._flushReactor()
59
80
 
60
81
  self.assertEqual(
61
- payload,
62
- self.deliveredPayloadEnvelope,
82
+ payload.filt,
83
+ self.deliveredPayloadEnvelope.filt,
63
84
  "PayloadIO/PayloadEndpoint delivery error",
64
85
  )
65
86
 
87
+ @inlineCallbacks
66
88
  def testFiltValueUnmatched(self):
67
89
  plFilt = {"key": "unittest", "This matches": 555}
68
90
  epFilt = {"key": "unittest", "This matches": 0}
69
91
 
70
- self._testBuild(plFilt, epFilt)
92
+ self._registerAndProcess(plFilt, epFilt)
93
+ yield self._flushReactor()
71
94
 
72
95
  self.assertEqual(
73
96
  self.deliveredPayloadEnvelope,
@@ -75,11 +98,13 @@ class PayloadEndpointPyTest(unittest.TestCase):
75
98
  "PayloadIO/PayloadEndpoint unmatched value test error",
76
99
  )
77
100
 
101
+ @inlineCallbacks
78
102
  def testFiltKeyUnmatched(self):
79
103
  plFilt = {"key": "unittest", "This matches": 555}
80
104
  epFilt = {"key": "unittest", "This doesnt matches": 555}
81
105
 
82
- self._testBuild(plFilt, epFilt)
106
+ self._registerAndProcess(plFilt, epFilt)
107
+ yield self._flushReactor()
83
108
 
84
109
  self.assertEqual(
85
110
  self.deliveredPayloadEnvelope,
@@ -87,11 +112,10 @@ class PayloadEndpointPyTest(unittest.TestCase):
87
112
  "PayloadIO/PayloadEndpoint unmatched value test error",
88
113
  )
89
114
 
115
+ @inlineCallbacks
90
116
  def testFunctionGoesOutOfScope(self):
91
117
  filt = {"key": "unittest", "This matches": 555}
92
-
93
- payload = Payload()
94
- payload.filt = filt
118
+ payload = self._newPayload(filt)
95
119
 
96
120
  def subScope():
97
121
  def outOfScopeFunc(
@@ -99,15 +123,12 @@ class PayloadEndpointPyTest(unittest.TestCase):
99
123
  ):
100
124
  self.deliveredPayloadEnvelope = payloadEnvelope
101
125
 
102
- PayloadEndpoint(filt, outOfScopeFunc, requiredPermissions=frozenset())
126
+ PayloadEndpoint(
127
+ filt, outOfScopeFunc, requiredPermissions=frozenset()
128
+ )
103
129
 
104
- PayloadIO().process(
105
- payloadEnvelope=payload.makePayloadEnvelope(),
106
- vortexUuid="test",
107
- vortexName="test",
108
- vortexSession=None,
109
- sendResponse=lambda x: x,
110
- )
130
+ self._processEnvelope(payload)
131
+ yield self._flushReactor()
111
132
 
112
133
  self.assertEqual(
113
134
  self.deliveredPayloadEnvelope,
@@ -115,23 +136,19 @@ class PayloadEndpointPyTest(unittest.TestCase):
115
136
  "PayloadIO/PayloadEndpoint unmatched value test error",
116
137
  )
117
138
 
139
+ @inlineCallbacks
118
140
  def testClassGoesOutOdScope(self):
119
141
  filt = {"key": "unittest", "This matches": 555}
120
-
121
- payload = Payload()
122
- payload.filt = filt
142
+ payload = self._newPayload(filt)
123
143
 
124
144
  def subScope():
125
145
  inst = PayloadEndpointPyTestAssignPayload(self)
126
- PayloadEndpoint(filt, inst.process, requiredPermissions=frozenset())
146
+ PayloadEndpoint(
147
+ filt, inst.process, requiredPermissions=frozenset()
148
+ )
127
149
 
128
- PayloadIO().process(
129
- payloadEnvelope=payload.makePayloadEnvelope(),
130
- vortexUuid="test",
131
- vortexName="test",
132
- vortexSession=None,
133
- sendResponse=lambda x: x,
134
- )
150
+ self._processEnvelope(payload)
151
+ yield self._flushReactor()
135
152
 
136
153
  self.assertEqual(
137
154
  self.deliveredPayloadEnvelope,
@@ -139,25 +156,19 @@ class PayloadEndpointPyTest(unittest.TestCase):
139
156
  "PayloadIO/PayloadEndpoint unmatched value test error",
140
157
  )
141
158
 
159
+ @inlineCallbacks
142
160
  def testClassStaysInScope(self):
143
161
  filt = {"key": "unittest", "This matches": 555}
144
-
145
- payload = Payload()
146
- payload.filt = filt
162
+ payload = self._newPayload(filt)
147
163
 
148
164
  inst = PayloadEndpointPyTestAssignPayload(self)
149
165
  PayloadEndpoint(filt, inst.process, requiredPermissions=frozenset())
150
166
 
151
- PayloadIO().process(
152
- payloadEnvelope=payload.makePayloadEnvelope(),
153
- vortexUuid="test",
154
- vortexName="test",
155
- vortexSession=None,
156
- sendResponse=lambda x: x,
157
- )
167
+ self._processEnvelope(payload)
168
+ yield self._flushReactor()
158
169
 
159
170
  self.assertEqual(
160
- self.deliveredPayloadEnvelope,
161
- payload,
171
+ payload.filt,
172
+ self.deliveredPayloadEnvelope.filt,
162
173
  "PayloadIO/PayloadEndpoint unmatched value test error",
163
174
  )
@@ -446,8 +446,14 @@ class VortexFactory:
446
446
  yield deferLater(reactor, 0.05, lambda: None)
447
447
 
448
448
  while cls.__listeningPorts:
449
- cls.__listeningPorts.pop().stopListening()
450
- yield deferLater(reactor, 0.05, lambda: None)
449
+ stopDeferred = cls.__listeningPorts.pop().stopListening()
450
+ if stopDeferred is not None:
451
+ yield stopDeferred
452
+
453
+ # Let Twisted finish unregistering closed ports from the reactor
454
+ # before before-shutdown returns — avoids epoll Bad file descriptor
455
+ # spam when other before-shutdown handlers close sockets next.
456
+ yield deferLater(reactor, 0.05, lambda: None)
451
457
 
452
458
  cls.__vortexInfoState = _VortexFactoryVortexInfo()
453
459
 
@@ -6,4 +6,4 @@
6
6
  # Website : https://flyingion.com
7
7
  # Support : contact@flyingion.com
8
8
 
9
- __version__ = '4.0.28'
9
+ __version__ = '4.0.29'
@@ -163,6 +163,29 @@ class TupleChangeEventBus:
163
163
 
164
164
  self._weakObserversBySelectorName[eventName].add(observer)
165
165
 
166
+ def removeObserver(
167
+ self,
168
+ observer: TupleChangeEventBusObserverABC,
169
+ eventNameOrClass: Optional[
170
+ Union[
171
+ str,
172
+ Type[TupleChangeEventABC],
173
+ TupleChangeEventABC,
174
+ ]
175
+ ] = None,
176
+ ) -> None:
177
+ assert isinstance(
178
+ observer, TupleChangeEventBusObserverABC
179
+ ), "observer must be a TupleChangeEventBusObserverABC"
180
+
181
+ if eventNameOrClass is None:
182
+ self._weakObserversForAllTupleChangeEventABCNames.discard(observer)
183
+ return
184
+
185
+ eventName = self._nameFromEvent(eventNameOrClass)
186
+
187
+ self._weakObserversBySelectorName[eventName].discard(observer)
188
+
166
189
  # noinspection PyMethodMayBeStatic
167
190
  def _nameFromEvent(
168
191
  self,
@@ -1,31 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vortexpy
3
- Version: 4.0.28
3
+ Version: 4.0.29
4
4
  Summary: Flying Ion's observable, routable, data serialisation and transport code.
5
5
  Author-email: Flying Ion Pty Ltd <contact@flyingion.com>
6
- License: MIT License
7
-
8
- Copyright (c) 2016-2026 Flying Ion Pty Ltd
9
-
10
- Permission is hereby granted, free of charge, to any person obtaining a copy
11
- of this software and associated documentation files (the "Software"), to deal
12
- in the Software without restriction, including without limitation the rights
13
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
- copies of the Software, and to permit persons to whom the Software is
15
- furnished to do so, subject to the following conditions:
16
-
17
- The above copyright notice and this permission notice shall be included in all
18
- copies or substantial portions of the Software.
19
-
20
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
- SOFTWARE.
27
-
28
-
6
+ License: MIT
29
7
  Project-URL: Homepage, https://flyingion.com
30
8
  Project-URL: Repository, https://gitlab.com/flyingion/vortexpy
31
9
  Project-URL: Issues, https://gitlab.com/flyingion/vortexpy/-/issues
@@ -1,4 +1,3 @@
1
- LICENSE
2
1
  README.md
3
2
  pyproject.toml
4
3
  vortex/DataWrapTuple.py
vortexpy-4.0.28/LICENSE DELETED
@@ -1,22 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2016-2026 Flying Ion Pty Ltd
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
22
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes