Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PKG-INFO 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. Metadata-Version: 1.1
  2. Name: Acquisition
  3. Version: 4.5
  4. Summary: Acquisition is a mechanism that allows objects to obtain attributes from the containment hierarchy they're in.
  5. Home-page: https://github.com/zopefoundation/Acquisition
  6. Author: Zope Foundation and Contributors
  7. Author-email: zope-dev@zope.org
  8. License: ZPL 2.1
  9. Description: Environmental Acquisiton
  10. ========================
  11. This package implements "environmental acquisiton" for Python, as
  12. proposed in the OOPSLA96_ paper by Joseph Gil and David H. Lorenz:
  13. We propose a new programming paradigm, environmental acquisition in
  14. the context of object aggregation, in which objects acquire
  15. behaviour from their current containers at runtime. The key idea is
  16. that the behaviour of a component may depend upon its enclosing
  17. composite(s). In particular, we propose a form of feature sharing in
  18. which an object "inherits" features from the classes of objects in
  19. its environment. By examining the declaration of classes, it is
  20. possible to determine which kinds of classes may contain a
  21. component, and which components must be contained in a given kind of
  22. composite. These relationships are the basis for language constructs
  23. that supports acquisition.
  24. .. _OOPSLA96: http://www.cs.virginia.edu/~lorenz/papers/oopsla96/>`_:
  25. .. contents::
  26. Introductory Example
  27. --------------------
  28. Zope implements acquisition with "Extension Class" mix-in classes. To
  29. use acquisition your classes must inherit from an acquisition base
  30. class. For example::
  31. >>> import ExtensionClass, Acquisition
  32. >>> class C(ExtensionClass.Base):
  33. ... color = 'red'
  34. >>> class A(Acquisition.Implicit):
  35. ... def report(self):
  36. ... print(self.color)
  37. ...
  38. >>> a = A()
  39. >>> c = C()
  40. >>> c.a = a
  41. >>> c.a.report()
  42. red
  43. >>> d = C()
  44. >>> d.color = 'green'
  45. >>> d.a = a
  46. >>> d.a.report()
  47. green
  48. >>> try:
  49. ... a.report()
  50. ... except AttributeError:
  51. ... pass
  52. ... else:
  53. ... raise AssertionError('AttributeError not raised.')
  54. The class ``A`` inherits acquisition behavior from
  55. ``Acquisition.Implicit``. The object, ``a``, "has" the color of
  56. objects ``c`` and d when it is accessed through them, but it has no
  57. color by itself. The object ``a`` obtains attributes from its
  58. environment, where its environment is defined by the access path used
  59. to reach ``a``.
  60. Acquisition Wrappers
  61. --------------------
  62. When an object that supports acquisition is accessed through an
  63. extension class instance, a special object, called an acquisition
  64. wrapper, is returned. In the example above, the expression ``c.a``
  65. returns an acquisition wrapper that contains references to both ``c``
  66. and ``a``. It is this wrapper that performs attribute lookup in ``c``
  67. when an attribute cannot be found in ``a``.
  68. Acquisition wrappers provide access to the wrapped objects through the
  69. attributes ``aq_parent``, ``aq_self``, ``aq_base``. Continue the
  70. example from above::
  71. >>> c.a.aq_parent is c
  72. True
  73. >>> c.a.aq_self is a
  74. True
  75. Explicit and Implicit Acquisition
  76. ---------------------------------
  77. Two styles of acquisition are supported: implicit and explicit
  78. acquisition.
  79. Implicit acquisition
  80. --------------------
  81. Implicit acquisition is so named because it searches for attributes
  82. from the environment automatically whenever an attribute cannot be
  83. obtained directly from an object or through inheritance.
  84. An attribute can be implicitly acquired if its name does not begin
  85. with an underscore.
  86. To support implicit acquisition, your class should inherit from the
  87. mix-in class ``Acquisition.Implicit``.
  88. Explicit Acquisition
  89. --------------------
  90. When explicit acquisition is used, attributes are not automatically
  91. obtained from the environment. Instead, the method aq_acquire must be
  92. used. For example::
  93. >>> print(c.a.aq_acquire('color'))
  94. red
  95. To support explicit acquisition, your class should inherit from the
  96. mix-in class ``Acquisition.Explicit``.
  97. Controlling Acquisition
  98. -----------------------
  99. A class (or instance) can provide attribute by attribute control over
  100. acquisition. Your should subclass from ``Acquisition.Explicit``, and set
  101. all attributes that should be acquired to the special value
  102. ``Acquisition.Acquired``. Setting an attribute to this value also allows
  103. inherited attributes to be overridden with acquired ones. For example::
  104. >>> class C(Acquisition.Explicit):
  105. ... id = 1
  106. ... secret = 2
  107. ... color = Acquisition.Acquired
  108. ... __roles__ = Acquisition.Acquired
  109. The only attributes that are automatically acquired from containing
  110. objects are color, and ``__roles__``. Note that the ``__roles__``
  111. attribute is acquired even though its name begins with an
  112. underscore. In fact, the special ``Acquisition.Acquired`` value can be
  113. used in ``Acquisition.Implicit`` objects to implicitly acquire
  114. selected objects that smell like private objects.
  115. Sometimes, you want to dynamically make an implicitly acquiring object
  116. acquire explicitly. You can do this by getting the object's
  117. aq_explicit attribute. This attribute provides the object with an
  118. explicit wrapper that replaces the original implicit wrapper.
  119. Filtered Acquisition
  120. --------------------
  121. The acquisition method, ``aq_acquire``, accepts two optional
  122. arguments. The first of the additional arguments is a "filtering"
  123. function that is used when considering whether to acquire an
  124. object. The second of the additional arguments is an object that is
  125. passed as extra data when calling the filtering function and which
  126. defaults to ``None``. The filter function is called with five
  127. arguments:
  128. * The object that the aq_acquire method was called on,
  129. * The object where an object was found,
  130. * The name of the object, as passed to aq_acquire,
  131. * The object found, and
  132. * The extra data passed to aq_acquire.
  133. If the filter returns a true object that the object found is returned,
  134. otherwise, the acquisition search continues.
  135. Here's an example::
  136. >>> from Acquisition import Explicit
  137. >>> class HandyForTesting(object):
  138. ... def __init__(self, name):
  139. ... self.name = name
  140. ... def __str__(self):
  141. ... return "%s(%s)" % (self.name, self.__class__.__name__)
  142. ... __repr__=__str__
  143. ...
  144. >>> class E(Explicit, HandyForTesting): pass
  145. ...
  146. >>> class Nice(HandyForTesting):
  147. ... isNice = 1
  148. ... def __str__(self):
  149. ... return HandyForTesting.__str__(self)+' and I am nice!'
  150. ... __repr__ = __str__
  151. ...
  152. >>> a = E('a')
  153. >>> a.b = E('b')
  154. >>> a.b.c = E('c')
  155. >>> a.p = Nice('spam')
  156. >>> a.b.p = E('p')
  157. >>> def find_nice(self, ancestor, name, object, extra):
  158. ... return hasattr(object,'isNice') and object.isNice
  159. >>> print(a.b.c.aq_acquire('p', find_nice))
  160. spam(Nice) and I am nice!
  161. The filtered acquisition in the last line skips over the first
  162. attribute it finds with the name ``p``, because the attribute doesn't
  163. satisfy the condition given in the filter.
  164. Filtered acquisition is rarely used in Zope.
  165. Acquiring from Context
  166. ----------------------
  167. Normally acquisition allows objects to acquire data from their
  168. containers. However an object can acquire from objects that aren't its
  169. containers.
  170. Most of the examples we've seen so far show establishing of an
  171. acquisition context using getattr semantics. For example, ``a.b`` is a
  172. reference to ``b`` in the context of ``a``.
  173. You can also manually set acquisition context using the ``__of__``
  174. method. For example::
  175. >>> from Acquisition import Implicit
  176. >>> class C(Implicit): pass
  177. ...
  178. >>> a = C()
  179. >>> b = C()
  180. >>> a.color = "red"
  181. >>> print(b.__of__(a).color)
  182. red
  183. In this case, ``a`` does not contain ``b``, but it is put in ``b``'s
  184. context using the ``__of__`` method.
  185. Here's another subtler example that shows how you can construct an
  186. acquisition context that includes non-container objects::
  187. >>> from Acquisition import Implicit
  188. >>> class C(Implicit):
  189. ... def __init__(self, name):
  190. ... self.name = name
  191. >>> a = C("a")
  192. >>> a.b = C("b")
  193. >>> a.b.color = "red"
  194. >>> a.x = C("x")
  195. >>> print(a.b.x.color)
  196. red
  197. Even though ``b`` does not contain ``x``, ``x`` can acquire the color
  198. attribute from ``b``. This works because in this case, ``x`` is accessed
  199. in the context of ``b`` even though it is not contained by ``b``.
  200. Here acquisition context is defined by the objects used to access
  201. another object.
  202. Containment Before Context
  203. --------------------------
  204. If in the example above suppose both a and b have an color attribute::
  205. >>> a = C("a")
  206. >>> a.color = "green"
  207. >>> a.b = C("b")
  208. >>> a.b.color = "red"
  209. >>> a.x = C("x")
  210. >>> print(a.b.x.color)
  211. green
  212. Why does ``a.b.x.color`` acquire color from ``a`` and not from ``b``?
  213. The answer is that an object acquires from its containers before
  214. non-containers in its context.
  215. To see why consider this example in terms of expressions using the
  216. ``__of__`` method::
  217. a.x -> x.__of__(a)
  218. a.b -> b.__of__(a)
  219. a.b.x -> x.__of__(a).__of__(b.__of__(a))
  220. Keep in mind that attribute lookup in a wrapper is done by trying to
  221. look up the attribute in the wrapped object first and then in the
  222. parent object. So in the expressions above proceeds from left to
  223. right.
  224. The upshot of these rules is that attributes are looked up by
  225. containment before context.
  226. This rule holds true also for more complex examples. For example,
  227. ``a.b.c.d.e.f.g.attribute`` would search for attribute in ``g`` and
  228. all its containers first. (Containers are searched in order from the
  229. innermost parent to the outermost container.) If the attribute is not
  230. found in ``g`` or any of its containers, then the search moves to
  231. ``f`` and all its containers, and so on.
  232. Additional Attributes and Methods
  233. ---------------------------------
  234. You can use the special method ``aq_inner`` to access an object
  235. wrapped only by containment. So in the example above,
  236. ``a.b.x.aq_inner`` is equivalent to ``a.x``.
  237. You can find out the acquisition context of an object using the
  238. aq_chain method like so:
  239. >>> [obj.name for obj in a.b.x.aq_chain]
  240. ['x', 'b', 'a']
  241. You can find out if an object is in the containment context of another
  242. object using the ``aq_inContextOf`` method. For example:
  243. >>> a.b.aq_inContextOf(a)
  244. True
  245. .. Note: as of this writing the aq_inContextOf examples don't work the
  246. way they should be working. According to Jim, this is because
  247. aq_inContextOf works by comparing object pointer addresses, which
  248. (because they are actually different wrapper objects) doesn't give
  249. you the expected results. He acknowledges that this behavior is
  250. controversial, and says that there is a collector entry to change
  251. it so that you would get the answer you expect in the above. (We
  252. just need to get to it).
  253. Acquisition Module Functions
  254. ----------------------------
  255. In addition to using acquisition attributes and methods directly on
  256. objects you can use similar functions defined in the ``Acquisition``
  257. module. These functions have the advantage that you don't need to
  258. check to make sure that the object has the method or attribute before
  259. calling it.
  260. ``aq_acquire(object, name [, filter, extra, explicit, default, containment])``
  261. Acquires an object with the given name.
  262. This function can be used to explictly acquire when using explicit
  263. acquisition and to acquire names that wouldn't normally be
  264. acquired.
  265. The function accepts a number of optional arguments:
  266. ``filter``
  267. A callable filter object that is used to decide if an object
  268. should be acquired.
  269. The filter is called with five arguments:
  270. * The object that the aq_acquire method was called on,
  271. * The object where an object was found,
  272. * The name of the object, as passed to aq_acquire,
  273. * The object found, and
  274. * The extra argument passed to aq_acquire.
  275. If the filter returns a true object that the object found is
  276. returned, otherwise, the acquisition search continues.
  277. ``extra``
  278. Extra data to be passed as the last argument to the filter.
  279. ``explicit``
  280. A flag (boolean value) indicating whether explicit acquisition
  281. should be used. The default value is true. If the flag is
  282. true, then acquisition will proceed regardless of whether
  283. wrappers encountered in the search of the acquisition
  284. hierarchy are explicit or implicit wrappers. If the flag is
  285. false, then parents of explicit wrappers are not searched.
  286. This argument is useful if you want to apply a filter without
  287. overriding explicit wrappers.
  288. ``default``
  289. A default value to return if no value can be acquired.
  290. ``containment``
  291. A flag indicating whether the search should be limited to the
  292. containment hierarchy.
  293. In addition, arguments can be provided as keywords.
  294. ``aq_base(object)``
  295. Return the object with all wrapping removed.
  296. ``aq_chain(object [, containment])``
  297. Return a list containing the object and it's acquisition
  298. parents. The optional argument, containment, controls whether the
  299. containment or access hierarchy is used.
  300. ``aq_get(object, name [, default, containment])``
  301. Acquire an attribute, name. A default value can be provided, as
  302. can a flag that limits search to the containment hierarchy.
  303. ``aq_inner(object)``
  304. Return the object with all but the innermost layer of wrapping
  305. removed.
  306. ``aq_parent(object)``
  307. Return the acquisition parent of the object or None if the object
  308. is unwrapped.
  309. ``aq_self(object)``
  310. Return the object with one layer of wrapping removed, unless the
  311. object is unwrapped, in which case the object is returned.
  312. In most cases it is more convenient to use these module functions
  313. instead of the acquisition attributes and methods directly.
  314. Acquisition and Methods
  315. -----------------------
  316. Python methods of objects that support acquisition can use acquired
  317. attributes. When a Python method is called on an object that is
  318. wrapped by an acquisition wrapper, the wrapper is passed to the method
  319. as the first argument. This rule also applies to user-defined method
  320. types and to C methods defined in pure mix-in classes.
  321. Unfortunately, C methods defined in extension base classes that define
  322. their own data structures, cannot use aquired attributes at this
  323. time. This is because wrapper objects do not conform to the data
  324. structures expected by these methods. In practice, you will seldom
  325. find this a problem.
  326. Conclusion
  327. ----------
  328. Acquisition provides a powerful way to dynamically share information
  329. between objects. Zope 2 uses acquisition for a number of its key
  330. features including security, object publishing, and DTML variable
  331. lookup. Acquisition also provides an elegant solution to the problem
  332. of circular references for many classes of problems. While acquisition
  333. is powerful, you should take care when using acquisition in your
  334. applications. The details can get complex, especially with the
  335. differences between acquiring from context and acquiring from
  336. containment.
  337. Changelog
  338. =========
  339. 4.5 (2018-10-05)
  340. ----------------
  341. - Avoid deprecation warnings by using current API.
  342. - Add support for Python 3.7.
  343. 4.4.4 (2017-11-24)
  344. ------------------
  345. - Add Appveyor configuration to automate building Windows eggs.
  346. 4.4.3 (2017-11-23)
  347. ------------------
  348. - Fix the extremely rare potential for a crash when the C extensions
  349. are in use. See `issue 21 <https://github.com/zopefoundation/Acquisition/issues/21>`_.
  350. 4.4.2 (2017-05-12)
  351. ------------------
  352. - Fix C capsule name to fix import errors.
  353. - Ensure our dependencies match our expactations about C extensions.
  354. 4.4.1 (2017-05-04)
  355. ------------------
  356. - Fix C code under Python 3.4, with missing Py_XSETREF.
  357. 4.4.0 (2017-05-04)
  358. ------------------
  359. - Enable the C extension under Python 3.
  360. - Drop support for Python 3.3.
  361. 4.3.0 (2017-01-20)
  362. ------------------
  363. - Make tests compatible with ExtensionClass 4.2.0.
  364. - Drop support for Python 2.6 and 3.2.
  365. - Add support for Python 3.5 and 3.6.
  366. 4.2.2 (2015-05-19)
  367. ------------------
  368. - Make the pure-Python Acquirer objects cooperatively use the
  369. superclass ``__getattribute__`` method, like the C implementation.
  370. See https://github.com/zopefoundation/Acquisition/issues/7.
  371. - The pure-Python implicit acquisition wrapper allows wrapped objects
  372. to use ``object.__getattribute__(self, name)``. This differs from
  373. the C implementation, but is important for compatibility with the
  374. pure-Python versions of libraries like ``persistent``. See
  375. https://github.com/zopefoundation/Acquisition/issues/9.
  376. 4.2.1 (2015-04-23)
  377. ------------------
  378. - Correct several dangling pointer uses in the C extension,
  379. potentially fixing a few interpreter crashes. See
  380. https://github.com/zopefoundation/Acquisition/issues/5.
  381. 4.2 (2015-04-04)
  382. ----------------
  383. - Add support for PyPy, PyPy3, and Python 3.2, 3.3, and 3.4.
  384. 4.1 (2014-12-18)
  385. ----------------
  386. - Bump dependency on ``ExtensionClass`` to match current release.
  387. 4.0.3 (2014-11-02)
  388. ------------------
  389. - Skip readme.rst tests when tests are run outside a source checkout.
  390. 4.0.2 (2014-11-02)
  391. ------------------
  392. - Include ``*.rst`` files in the release.
  393. 4.0.1 (2014-10-30)
  394. ------------------
  395. - Tolerate Unicode attribute names (ASCII only). LP #143358.
  396. - Make module-level ``aq_acquire`` API respect the ``default`` parameter.
  397. LP #1387363.
  398. - Don't raise an attribute error for ``__iter__`` if the fallback to
  399. ``__getitem__`` succeeds. LP #1155760.
  400. 4.0 (2013-02-24)
  401. ----------------
  402. - Added trove classifiers to project metadata.
  403. 4.0a1 (2011-12-13)
  404. ------------------
  405. - Raise `RuntimeError: Recursion detected in acquisition wrapper` if an object
  406. with a `__parent__` pointer points to a wrapper that in turn points to the
  407. original object.
  408. - Prevent wrappers to be created while accessing `__parent__` on types derived
  409. from Explicit or Implicit base classes.
  410. 2.13.9 (2015-02-17)
  411. -------------------
  412. - Tolerate Unicode attribute names (ASCII only). LP #143358.
  413. - Make module-level ``aq_acquire`` API respect the ``default`` parameter.
  414. LP #1387363.
  415. - Don't raise an attribute error for ``__iter__`` if the fallback to
  416. ``__getitem__`` succeeds. LP #1155760.
  417. 2.13.8 (2011-06-11)
  418. -------------------
  419. - Fixed a segfault on 64bit platforms when providing the `explicit` argument to
  420. the aq_acquire method of an Acquisition wrapper. Thx to LP #675064 for the
  421. hint to the solution. The code passed an int instead of a pointer into a
  422. function.
  423. 2.13.7 (2011-03-02)
  424. -------------------
  425. - Fixed bug: When an object did not implement ``__unicode__``, calling
  426. ``unicode(wrapped)`` was calling ``__str__`` with an unwrapped ``self``.
  427. 2.13.6 (2011-02-19)
  428. -------------------
  429. - Add ``aq_explicit`` to ``IAcquisitionWrapper``.
  430. - Fixed bug: ``unicode(wrapped)`` was not calling a ``__unicode__``
  431. method on wrapped objects.
  432. 2.13.5 (2010-09-29)
  433. -------------------
  434. - Fixed unit tests that failed on 64bit Python on Windows machines.
  435. 2.13.4 (2010-08-31)
  436. -------------------
  437. - LP 623665: Fixed typo in Acquisition.h.
  438. 2.13.3 (2010-04-19)
  439. -------------------
  440. - Use the doctest module from the standard library and no longer depend on
  441. zope.testing.
  442. 2.13.2 (2010-04-04)
  443. -------------------
  444. - Give both wrapper classes a ``__getnewargs__`` method, which causes the ZODB
  445. optimization to fail and create persistent references using the ``_p_oid``
  446. alone. This happens to be the persistent oid of the wrapped object. This lets
  447. these objects to be persisted correctly, even though they are passed to the
  448. ZODB in a wrapped state.
  449. - Added failing tests for http://dev.plone.org/plone/ticket/10318. This shows
  450. an edge-case where AQ wrappers can be pickled using the specific combination
  451. of cPickle, pickle protocol one and a custom Pickler class with an
  452. ``inst_persistent_id`` hook. Unfortunately this is the exact combination used
  453. by ZODB3.
  454. 2.13.1 (2010-02-23)
  455. -------------------
  456. - Update to include ExtensionClass 2.13.0.
  457. - Fix the ``tp_name`` of the ImplicitAcquisitionWrapper and
  458. ExplicitAcquisitionWrapper to match their Python visible names and thus have
  459. a correct ``__name__``.
  460. - Expand the ``tp_name`` of our extension types to hold the fully qualified
  461. name. This ensures classes have their ``__module__`` set correctly.
  462. 2.13.0 (2010-02-14)
  463. -------------------
  464. - Added support for method cache in Acquisition. Patch contributed by
  465. Yoshinori K. Okuji. See https://bugs.launchpad.net/zope2/+bug/486182.
  466. 2.12.4 (2009-10-29)
  467. -------------------
  468. - Fix iteration proxying to pass `self` acquisition-wrapped into both
  469. `__iter__` as well as `__getitem__` (this fixes
  470. https://bugs.launchpad.net/zope2/+bug/360761).
  471. - Add tests for the __getslice__ proxying, including open-ended slicing.
  472. 2.12.3 (2009-08-08)
  473. -------------------
  474. - More 64-bit fixes in Py_BuildValue calls.
  475. - More 64-bit issues fixed: Use correct integer size for slice operations.
  476. 2.12.2 (2009-08-02)
  477. -------------------
  478. - Fixed 64-bit compatibility issues for Python 2.5.x / 2.6.x. See
  479. http://www.python.org/dev/peps/pep-0353/ for details.
  480. 2.12.1 (2009-04-15)
  481. -------------------
  482. - Update for iteration proxying: The proxy for `__iter__` must not rely on the
  483. object to have an `__iter__` itself, but also support fall-back iteration via
  484. `__getitem__` (this fixes https://bugs.launchpad.net/zope2/+bug/360761).
  485. 2.12 (2009-01-25)
  486. -----------------
  487. - Release as separate package.
  488. Platform: UNKNOWN
  489. Classifier: Development Status :: 6 - Mature
  490. Classifier: Environment :: Web Environment
  491. Classifier: Framework :: Zope2
  492. Classifier: License :: OSI Approved :: Zope Public License
  493. Classifier: Operating System :: OS Independent
  494. Classifier: Programming Language :: Python
  495. Classifier: Programming Language :: Python :: 2
  496. Classifier: Programming Language :: Python :: 2.7
  497. Classifier: Programming Language :: Python :: 3
  498. Classifier: Programming Language :: Python :: 3.4
  499. Classifier: Programming Language :: Python :: 3.5
  500. Classifier: Programming Language :: Python :: 3.6
  501. Classifier: Programming Language :: Python :: 3.7
  502. Classifier: Programming Language :: Python :: Implementation :: CPython
  503. Classifier: Programming Language :: Python :: Implementation :: PyPy