other 2.0.0__py3-none-any.whl

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.
@@ -0,0 +1,69 @@
1
+ Metadata-Version: 2.4
2
+ Name: other
3
+ Version: 2.0.0
4
+ Summary: The Zen of Zope, by Alex Clark
5
+ Author-email: Alex Clark <aclark@aclark.net>
6
+ Project-URL: Homepage, https://github.com/aclark4life/other
7
+ Classifier: Framework :: Zope
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3 :: Only
10
+ Requires-Python: >=3.10
11
+ Description-Content-Type: text/x-rst
12
+ Requires-Dist: that
13
+ Requires-Dist: zope.component
14
+
15
+ The Zen of Zope, by Alex Clark
16
+ ==============================
17
+
18
+ ::
19
+
20
+ >>> import other
21
+ The Zen of Zope, by Alex Clark
22
+
23
+
24
+ Beautiful is an attribute of ugly.
25
+ Explicit is implemented by implicit.
26
+ Simple is provided by complex.
27
+ Complex is directly provided by complicated.
28
+ Flat only implements nested.
29
+ Sparse has tagged value dense.
30
+ Readability count is not in range.
31
+ Special cases could not adapt the rules.
32
+ Practicality implements purity.
33
+ Errors should never require a specification that doesn’t extend the specification of silence.
34
+ Unless explicit is a multi-adapter.
35
+ In subscribing to ambiguity, return all the objects that refuse the temptation to guess.
36
+ There should be none-- and preferably only zero --output from a handler.
37
+ Although that way may not be obvious at first unless you've registered an adapter hook
38
+ Now is verified by never.
39
+ Although never is not implemented by *right* now.
40
+ If the implementation is hard to explain, it queries the bad idea utility.
41
+ If the implementation is easy to explain, it may query the good idea utility.
42
+ Implicit namespace packages are one honking great idea -- let's do more of those!
43
+
44
+ Changes
45
+ =======
46
+
47
+ 2.0.0 (2026/10/22)
48
+ ------------------
49
+
50
+ - Drop Python 2; require Python 3.10+
51
+ [aclark]
52
+
53
+ - Use ``@implementer`` class decorators instead of ``implements()``
54
+ [aclark]
55
+
56
+ - Move packaging to ``pyproject.toml``
57
+ [aclark]
58
+
59
+ - Publish to PyPI with trusted publishing via GitHub Actions
60
+ [aclark]
61
+
62
+ - Add tests
63
+ [aclark]
64
+
65
+ 1.0.0 (2012/12/8)
66
+ -----------------
67
+
68
+ - First release
69
+ [aclark]
@@ -0,0 +1,5 @@
1
+ other.py,sha256=5WhtpMIFzhijENuZHzn-LKEyJBW2JCrKnOPjdpmuBgc,10058
2
+ other-2.0.0.dist-info/METADATA,sha256=YGfmip4rNF6wOCh5SN6QXXsI3u5hG9_6Mq2LFyEQwVs,2048
3
+ other-2.0.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
4
+ other-2.0.0.dist-info/top_level.txt,sha256=fk-i64x6wIlznV3vxEifrWihANkggso1xrQKRSSCH4c,6
5
+ other-2.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ other
other.py ADDED
@@ -0,0 +1,456 @@
1
+ # encoding: utf-8
2
+ from zope.interface import Attribute
3
+ from zope.interface import Interface
4
+ from zope.interface import Invalid
5
+ from zope.interface import directlyProvides
6
+ from zope.interface import directlyProvidedBy
7
+ from zope.interface import implementedBy
8
+ from zope.interface import implementer
9
+ from zope.interface import implementer_only
10
+ from zope.interface import invariant
11
+ from zope.interface import providedBy
12
+ from zope.interface.adapter import AdapterRegistry
13
+ from zope.interface.exceptions import BrokenImplementation
14
+ from zope.interface.interface import adapter_hooks
15
+ from zope.interface.verify import verifyObject
16
+
17
+ from zope.component import provideUtility
18
+ from zope.component import queryUtility
19
+
20
+ TITLE = "The Zen of Zope, by Alex Clark"
21
+
22
+ # This is a crash course on the Zope Component Architecture (ZCA), based on
23
+ # http://docs.zope.org/zope.interface/README.html and
24
+ # http://docs.zope.org/zope.component/index.html, and heavily inspired by
25
+ # The Anti-Zen of Python, by Daniel Greenfeld and
26
+ # The Zen of Python, by Tim Peters.
27
+ # Special thanks to Guido Van Rossum for Python, and Jim Fulton for Zope.
28
+ # Copyright (C) 2012 Alex Clark
29
+ # All rights reserved
30
+
31
+
32
+ __gittip_url__ = "https://www.gittip.com/aclark4life/"
33
+
34
+
35
+ class Complicated:
36
+ """
37
+ """
38
+
39
+
40
+ class INested(Interface):
41
+ """
42
+ """
43
+
44
+
45
+ @implementer(INested)
46
+ class Nested:
47
+ """
48
+ """
49
+
50
+
51
+
52
+ class ISparse(Interface):
53
+ """
54
+ """
55
+
56
+
57
+ class RangeError(Invalid):
58
+ """
59
+ """
60
+ def __repr__(self):
61
+ """
62
+ """
63
+ return "RangeError(%r)" % self.args
64
+
65
+
66
+ def range_invariant(ob):
67
+ """
68
+ """
69
+ if ob.max < ob.min:
70
+ raise RangeError(ob)
71
+
72
+
73
+ class IRange(Interface):
74
+ """
75
+ """
76
+ min = Attribute("Lower bound")
77
+ max = Attribute("Upper bound")
78
+ invariant(range_invariant)
79
+
80
+
81
+ @implementer(IRange)
82
+ class Range(object):
83
+ """
84
+ """
85
+
86
+ def __init__(self, min, max):
87
+ """
88
+ """
89
+ self.min, self.max = min, max
90
+
91
+ def __repr__(self):
92
+ """
93
+ """
94
+ return "Range(%s, %s)" % (self.min, self.max)
95
+
96
+
97
+ class ISpecialCases(Interface):
98
+ """
99
+ """
100
+
101
+
102
+ class IPurity(Interface):
103
+ """
104
+ """
105
+
106
+
107
+ @implementer(IPurity)
108
+ class Practicality(object):
109
+ """
110
+ """
111
+
112
+
113
+ class IErrors(Interface):
114
+ """
115
+ """
116
+
117
+
118
+ class ISilence(Interface):
119
+ """
120
+ """
121
+
122
+
123
+ class IPass(IErrors):
124
+ """
125
+ """
126
+
127
+
128
+ @implementer(IErrors)
129
+ class Errors:
130
+ """
131
+ """
132
+
133
+
134
+ @implementer(ISilence)
135
+ class Silence:
136
+ """
137
+ """
138
+
139
+
140
+
141
+
142
+ class IAmbiguity(Interface):
143
+ """
144
+ """
145
+
146
+
147
+ class IGuess(Interface):
148
+ """
149
+ """
150
+
151
+
152
+ def handler(event):
153
+ """
154
+ """
155
+ print('handler', event)
156
+
157
+
158
+ class IFile(Interface):
159
+ """
160
+ """
161
+ body = Attribute('Contents of the file.')
162
+
163
+
164
+ @implementer(IFile)
165
+ class File(object):
166
+ """
167
+ """
168
+ body = "Uniquely communicate economically sound infrastructures"
169
+
170
+
171
+ def hook(provided, object):
172
+ """
173
+ """
174
+ adapter = registry.lookup1(providedBy(object), provided, '')
175
+ return adapter(object)
176
+
177
+
178
+ class ISize(Interface):
179
+ """
180
+ """
181
+
182
+ def getSize():
183
+ """
184
+ """
185
+
186
+
187
+ @implementer(ISize)
188
+ class FileSize(object):
189
+ """
190
+ """
191
+
192
+ def __init__(self, context):
193
+ """
194
+ """
195
+ self.context = context
196
+
197
+ def getSize(self):
198
+ """
199
+ """
200
+ return len(self.context.body)
201
+
202
+
203
+ class INow(Interface):
204
+ """
205
+ """
206
+ x = Attribute("The X attribute")
207
+ y = Attribute("The Y attribute")
208
+
209
+
210
+ class INever(INow):
211
+ """
212
+ """
213
+
214
+
215
+ @implementer(INow)
216
+ class Never(object):
217
+ """
218
+ """
219
+ x = 1
220
+
221
+ def __init__(self):
222
+ self.y = 2
223
+
224
+
225
+ @implementer(INever)
226
+ class RightNow(object):
227
+ x = 1
228
+
229
+
230
+ class IImplementation(Interface):
231
+ """
232
+ """
233
+ def explain():
234
+ """
235
+ """
236
+
237
+
238
+ @implementer(IImplementation)
239
+ class Implementation:
240
+ """
241
+ """
242
+
243
+ def __init__(self, implementation="easy to explain, it may query the "
244
+ "good idea utility."):
245
+ """
246
+ """
247
+ self.implementation = implementation
248
+
249
+ def explain(self):
250
+ """
251
+ """
252
+ print("If the implementation is", self.implementation)
253
+
254
+
255
+ #------------------------------------------------------------------------------
256
+
257
+
258
+ print("%s\n\n" % TITLE)
259
+
260
+
261
+ # 1) Beautiful is better than ugly.
262
+
263
+ # Interfaces are objects that specify the behavior of objects that
264
+ # provide them, through:
265
+ # - Informal documentation e.g. doc strings
266
+ # - Attribute definitions
267
+ # - Invariants, which are conditions that must hold true for
268
+ # an object to provide an interface
269
+
270
+ class IPerson(Interface):
271
+ """
272
+ """
273
+ beautiful = Attribute("Beautiful is an attribute of person.")
274
+
275
+
276
+ @implementer(IPerson)
277
+ class Person(object):
278
+ """
279
+ """
280
+ beautiful = True
281
+
282
+
283
+ person = Person()
284
+ if hasattr(person, 'beautiful'):
285
+ print(IPerson['beautiful'].__doc__)
286
+
287
+
288
+ # 2) Explicit is better than implicit.
289
+ class IExplicit(Interface):
290
+ """
291
+ We say that objects provide interfaces. If an object provides an interface
292
+ then the interface specifies the behavior of the object. In other words,
293
+ interfaces specify the behavior of the objects that provide them.
294
+ """
295
+
296
+ @implementer(IExplicit)
297
+ class Implicit(object):
298
+ """
299
+ We normally say that classes implement interfaces. If a class implements an
300
+ interface, then the instances of the class provide the interface. Objects
301
+ provide interfaces that their classes implement [2]. (Objects can provide
302
+ interfaces directly, in addition to what their classes implement.)
303
+ """
304
+ @implementer(IExplicit)
305
+ class Explicit:
306
+
307
+ def __init__(self, errors, silence):
308
+ """
309
+ """
310
+ self.errors, self.silence = errors, silence
311
+
312
+
313
+ if IExplicit.implementedBy(Implicit):
314
+ print("Explicit is implemented by implicit.")
315
+
316
+
317
+ # 3) Simple is better than complex.
318
+ class IComplex(Interface):
319
+ """
320
+ """
321
+
322
+
323
+ @implementer(IComplex)
324
+ class Complex:
325
+ """
326
+ """
327
+
328
+
329
+ simple = Complex()
330
+ if IComplex.providedBy(simple):
331
+ print("Simple is provided by complex.")
332
+
333
+
334
+ # 4) Complex is better than complicated.
335
+ complicated = Complicated()
336
+ directlyProvides(complicated, IComplex)
337
+ for interface in directlyProvidedBy(complicated).interfaces():
338
+ if interface.getName() == 'IComplex':
339
+ print("Complex is directly provided by complicated.")
340
+
341
+
342
+ # 5) Flat is better than nested.
343
+ @implementer_only(INested)
344
+ class Flat(Complex):
345
+ """
346
+ """
347
+
348
+ interfaces = [interface for interface in implementedBy(Flat).interfaces()]
349
+ if len(interfaces) == 1:
350
+ if interfaces[0].getName() == 'INested':
351
+ print("Flat only implements nested.")
352
+
353
+
354
+ # 6) Sparse is better than dense.
355
+ ISparse.setTaggedValue('dense', 'Sparse has tagged value dense.')
356
+ tags = ISparse.getTaggedValueTags()
357
+ if 'dense' in tags:
358
+ print(ISparse.getTaggedValue('dense'))
359
+
360
+
361
+ # 7) Readability counts.
362
+ try:
363
+ IRange.validateInvariants(Range(2, 1))
364
+ except RangeError:
365
+ print("Readability count is not in range.")
366
+
367
+
368
+ # 8) Special cases aren't special enough to break the rules.
369
+ try:
370
+ ISpecialCases('the rules')
371
+ except TypeError:
372
+ print("Special cases could not adapt the rules.")
373
+
374
+
375
+ # 9) Although practicality beats purity.
376
+ practicality = Practicality()
377
+ if IPurity(practicality) is practicality:
378
+ print("Practicality implements purity.")
379
+
380
+
381
+ # 10) Errors should never pass silently.
382
+ # Register an object that depends on IErrors and provides ISilence
383
+ registry = AdapterRegistry() # XXX Logic below is not quite right
384
+ registry.register([IErrors], ISilence, 'should not', 'pass')
385
+ if (registry.lookup([IErrors], ISilence, 'should not') == 'pass' and
386
+ registry.lookup([Interface], ISilence) is None):
387
+ print ("Errors should never require a specification that doesn’t extend "
388
+ "the specification of silence.")
389
+
390
+
391
+ # 11) Unless explicitly silenced.
392
+ errors = Errors()
393
+ silence = Silence()
394
+ registry.register([IErrors, ISilence], IPass, '', Explicit)
395
+ explicit = registry.queryMultiAdapter((errors, silence), IPass)
396
+ if (explicit.__class__.__name__ == "Explicit" and
397
+ explicit.errors is errors and explicit.silence is silence):
398
+ print("Unless explicit is a multi-adapter.")
399
+
400
+
401
+ # 12) In the face of ambiguity, refuse the temptation to guess.
402
+ registry.subscribe([IAmbiguity], IGuess, 'refuse the temptation to guess')
403
+ if 'refuse the temptation to guess' in [sub for sub in
404
+ registry.subscriptions([IAmbiguity], IGuess)]:
405
+ print ("In subscribing to ambiguity, return all the objects that refuse "
406
+ "the temptation to guess.")
407
+
408
+
409
+ # 13) There should be one-- and preferably only one --obvious way to do it.
410
+ registry.subscribe([IErrors], None, handler)
411
+ if registry.subscriptions([IErrors], None) == [handler]:
412
+ print ("There should be none-- and preferably only zero --output from a "
413
+ "handler.")
414
+
415
+
416
+ # 14) Although that way may not be obvious at first unless you're Dutch.
417
+ adapter_hooks.append(hook)
418
+ registry.register([IFile], ISize, '', FileSize)
419
+ f = File()
420
+ size = ISize(f)
421
+ if registry.lookup1(IFile, ISize, '')(f).getSize() == size.getSize():
422
+ print ("Although that way may not be obvious at first unless you've "
423
+ "registered an adapter hook.")
424
+
425
+
426
+ # 15) Now is better than never.
427
+ never = Never()
428
+ if verifyObject(INow, never):
429
+ print("Now is verified by never.")
430
+
431
+
432
+ # 16) Although never is often better than *right* now.
433
+ right_now = RightNow()
434
+ try:
435
+ verifyObject(INever, right_now)
436
+ except BrokenImplementation:
437
+ print("Although never is not implemented by *right* now.")
438
+
439
+
440
+ # 17) If the implementation is hard to explain, it's a bad idea.
441
+ bad_idea = Implementation("hard to explain, it queries the bad idea "
442
+ "utility.") # XXX Logic?
443
+ provideUtility(bad_idea, IImplementation, 'bad idea')
444
+ queryUtility(IImplementation, 'bad idea').explain()
445
+
446
+
447
+ # 18) If the implementation is easy to explain, it may be a good idea.
448
+ good_idea = Implementation() # XXX Logic?
449
+ provideUtility(good_idea, IImplementation, 'good idea')
450
+ queryUtility(IImplementation, 'good idea').explain()
451
+
452
+
453
+ # 19) Namespaces are one honking great idea -- let's do more of those!
454
+ # http://www.python.org/dev/peps/pep-0420/
455
+ print ("Implicit namespace packages are one honking great idea -- let's do "
456
+ "more of those!")