Skip to main content

Environmental Acquisiton

This package implements “environmental acquisiton” for Python, as proposed in the OOPSLA96 paper by Joseph Gil and David H. Lorenz:

We propose a new programming paradigm, environmental acquisition in the context of object aggregation, in which objects acquire behaviour from their current containers at runtime. The key idea is that the behaviour of a component may depend upon its enclosing composite(s). In particular, we propose a form of feature sharing in which an object “inherits” features from the classes of objects in its environment. By examining the declaration of classes, it is possible to determine which kinds of classes may contain a component, and which components must be contained in a given kind of composite. These relationships are the basis for language constructs that supports acquisition.

Introductory Example

Zope implements acquisition with “Extension Class” mix-in classes. To use acquisition your classes must inherit from an acquisition base class. For example:

>>> import ExtensionClass, Acquisition

>>> class C(ExtensionClass.Base):
...     color = 'red'

>>> class A(Acquisition.Implicit):
...     def report(self):
...         print(self.color)
...
>>> a = A()
>>> c = C()
>>> c.a = a

>>> c.a.report()
red

>>> d = C()
>>> d.color = 'green'
>>> d.a = a

>>> d.a.report()
green

>>> try:
...     a.report()
... except AttributeError:
...     pass
... else:
...     raise AssertionError('AttributeError not raised.')

The class A inherits acquisition behavior from Acquisition.Implicit. The object, a, “has” the color of objects c and d when it is accessed through them, but it has no color by itself. The object a obtains attributes from its environment, where its environment is defined by the access path used to reach a.

Acquisition Wrappers

When an object that supports acquisition is accessed through an extension class instance, a special object, called an acquisition wrapper, is returned. In the example above, the expression c.a returns an acquisition wrapper that contains references to both c and a. It is this wrapper that performs attribute lookup in c when an attribute cannot be found in a.

Acquisition wrappers provide access to the wrapped objects through the attributes aq_parent, aq_self, aq_base. Continue the example from above:

>>> c.a.aq_parent is c
True
>>> c.a.aq_self is a
True

Explicit and Implicit Acquisition

Two styles of acquisition are supported: implicit and explicit acquisition.

Implicit acquisition

Implicit acquisition is so named because it searches for attributes from the environment automatically whenever an attribute cannot be obtained directly from an object or through inheritance.

An attribute can be implicitly acquired if its name does not begin with an underscore.

To support implicit acquisition, your class should inherit from the mix-in class Acquisition.Implicit.

Explicit Acquisition

When explicit acquisition is used, attributes are not automatically obtained from the environment. Instead, the method aq_acquire must be used. For example:

>>> print(c.a.aq_acquire('color'))
red

To support explicit acquisition, your class should inherit from the mix-in class Acquisition.Explicit.

Controlling Acquisition

A class (or instance) can provide attribute by attribute control over acquisition. You should subclass from Acquisition.Explicit, and set all attributes that should be acquired to the special value Acquisition.Acquired. Setting an attribute to this value also allows inherited attributes to be overridden with acquired ones. For example:

>>> class C(Acquisition.Explicit):
...     id = 1
...     secret = 2
...     color = Acquisition.Acquired
...     __roles__ = Acquisition.Acquired

The only attributes that are automatically acquired from containing objects are color, and __roles__. Note that the __roles__ attribute is acquired even though its name begins with an underscore. In fact, the special Acquisition.Acquired value can be used in Acquisition.Implicit objects to implicitly acquire selected objects that smell like private objects.

Sometimes, you want to dynamically make an implicitly acquiring object acquire explicitly. You can do this by getting the object’s aq_explicit attribute. This attribute provides the object with an explicit wrapper that replaces the original implicit wrapper.

Filtered Acquisition

The acquisition method, aq_acquire, accepts two optional arguments. The first of the additional arguments is a “filtering” function that is used when considering whether to acquire an object. The second of the additional arguments is an object that is passed as extra data when calling the filtering function and which defaults to None. The filter function is called with five arguments:

  • The object that the aq_acquire method was called on,

  • The object where an object was found,

  • The name of the object, as passed to aq_acquire,

  • The object found, and

  • The extra data passed to aq_acquire.

If the filter returns a true object that the object found is returned, otherwise, the acquisition search continues.

Here’s an example:

>>> from Acquisition import Explicit

>>> class HandyForTesting(object):
...     def __init__(self, name):
...         self.name = name
...     def __str__(self):
...         return "%s(%s)" % (self.name, self.__class__.__name__)
...     __repr__=__str__
...
>>> class E(Explicit, HandyForTesting): pass
...
>>> class Nice(HandyForTesting):
...     isNice = 1
...     def __str__(self):
...         return HandyForTesting.__str__(self)+' and I am nice!'
...     __repr__ = __str__
...
>>> a = E('a')
>>> a.b = E('b')
>>> a.b.c = E('c')
>>> a.p = Nice('spam')
>>> a.b.p = E('p')

>>> def find_nice(self, ancestor, name, object, extra):
...     return hasattr(object,'isNice') and object.isNice

>>> print(a.b.c.aq_acquire('p', find_nice))
spam(Nice) and I am nice!

The filtered acquisition in the last line skips over the first attribute it finds with the name p, because the attribute doesn’t satisfy the condition given in the filter.

Filtered acquisition is rarely used in Zope.

Acquiring from Context

Normally acquisition allows objects to acquire data from their containers. However an object can acquire from objects that aren’t its containers.

Most of the examples we’ve seen so far show establishing of an acquisition context using getattr semantics. For example, a.b is a reference to b in the context of a.

You can also manually set acquisition context using the __of__ method. For example:

>>> from Acquisition import Implicit
>>> class C(Implicit): pass
...
>>> a = C()
>>> b = C()
>>> a.color = "red"
>>> print(b.__of__(a).color)
red

In this case, a does not contain b, but it is put in b’s context using the __of__ method.

Here’s another subtler example that shows how you can construct an acquisition context that includes non-container objects:

>>> from Acquisition import Implicit

>>> class C(Implicit):
...     def __init__(self, name):
...         self.name = name

>>> a = C("a")
>>> a.b = C("b")
>>> a.b.color = "red"
>>> a.x = C("x")

>>> print(a.b.x.color)
red

Even though b does not contain x, x can acquire the color attribute from b. This works because in this case, x is accessed in the context of b even though it is not contained by b.

Here acquisition context is defined by the objects used to access another object.

Containment Before Context

If in the example above suppose both a and b have an color attribute:

>>> a = C("a")
>>> a.color = "green"
>>> a.b = C("b")
>>> a.b.color = "red"
>>> a.x = C("x")

>>> print(a.b.x.color)
green

Why does a.b.x.color acquire color from a and not from b? The answer is that an object acquires from its containers before non-containers in its context.

To see why consider this example in terms of expressions using the __of__ method:

a.x -> x.__of__(a)

a.b -> b.__of__(a)

a.b.x -> x.__of__(a).__of__(b.__of__(a))

Keep in mind that attribute lookup in a wrapper is done by trying to look up the attribute in the wrapped object first and then in the parent object. So in the expressions above proceeds from left to right.

The upshot of these rules is that attributes are looked up by containment before context.

This rule holds true also for more complex examples. For example, a.b.c.d.e.f.g.attribute would search for attribute in g and all its containers first. (Containers are searched in order from the innermost parent to the outermost container.) If the attribute is not found in g or any of its containers, then the search moves to f and all its containers, and so on.

Additional Attributes and Methods

You can use the special method aq_inner to access an object wrapped only by containment. So in the example above, a.b.x.aq_inner is equivalent to a.x.

You can find out the acquisition context of an object using the aq_chain method like so:

>>> [obj.name for obj in a.b.x.aq_chain]
['x', 'b', 'a']

You can find out if an object is in the containment context of another object using the aq_inContextOf method. For example:

>>> a.b.aq_inContextOf(a)
True

Acquisition Module Functions

In addition to using acquisition attributes and methods directly on objects you can use similar functions defined in the Acquisition module. These functions have the advantage that you don’t need to check to make sure that the object has the method or attribute before calling it.

aq_acquire(object, name [, filter, extra, explicit, default, containment])

Acquires an object with the given name.

This function can be used to explictly acquire when using explicit acquisition and to acquire names that wouldn’t normally be acquired.

The function accepts a number of optional arguments:

filter

A callable filter object that is used to decide if an object should be acquired.

The filter is called with five arguments:

  • The object that the aq_acquire method was called on,

  • The object where an object was found,

  • The name of the object, as passed to aq_acquire,

  • The object found, and

  • The extra argument passed to aq_acquire.

If the filter returns a true object that the object found is returned, otherwise, the acquisition search continues.

extra

Extra data to be passed as the last argument to the filter.

explicit

A flag (boolean value) indicating whether explicit acquisition should be used. The default value is true. If the flag is true, then acquisition will proceed regardless of whether wrappers encountered in the search of the acquisition hierarchy are explicit or implicit wrappers. If the flag is false, then parents of explicit wrappers are not searched.

This argument is useful if you want to apply a filter without overriding explicit wrappers.

default

A default value to return if no value can be acquired.

containment

A flag indicating whether the search should be limited to the containment hierarchy.

In addition, arguments can be provided as keywords.

aq_base(object)

Return the object with all wrapping removed.

aq_chain(object [, containment])

Return a list containing the object and it’s acquisition parents. The optional argument, containment, controls whether the containment or access hierarchy is used.

aq_get(object, name [, default, containment])

Acquire an attribute, name. A default value can be provided, as can a flag that limits search to the containment hierarchy.

aq_inner(object)

Return the object with all but the innermost layer of wrapping removed.

aq_parent(object)

Return the acquisition parent of the object or None if the object is unwrapped.

aq_self(object)

Return the object with one layer of wrapping removed, unless the object is unwrapped, in which case the object is returned.

In most cases it is more convenient to use these module functions instead of the acquisition attributes and methods directly.

Acquisition and Methods

Python methods of objects that support acquisition can use acquired attributes. When a Python method is called on an object that is wrapped by an acquisition wrapper, the wrapper is passed to the method as the first argument. This rule also applies to user-defined method types and to C methods defined in pure mix-in classes.

Unfortunately, C methods defined in extension base classes that define their own data structures, cannot use aquired attributes at this time. This is because wrapper objects do not conform to the data structures expected by these methods. In practice, you will seldom find this a problem.

Conclusion

Acquisition provides a powerful way to dynamically share information between objects. Zope uses acquisition for a number of its key features including security, object publishing, and DTML variable lookup. Acquisition also provides an elegant solution to the problem of circular references for many classes of problems. While acquisition is powerful, you should take care when using acquisition in your applications. The details can get complex, especially with the differences between acquiring from context and acquiring from containment.

Changelog

5.1 (2023-10-05)

  • Add support for Python 3.12.

5.0 (2023-03-24)

  • Build Linux binary wheels for Python 3.11.

  • Drop support for Python 2.7, 3.5, 3.6.

  • Add preliminary support for Python 3.12a5.

4.13 (2022-11-17)

  • Add support for building arm64 wheels on macOS.

4.12 (2022-11-03)

  • Add support for final Python 3.11 release.

4.11 (2022-09-16)

  • Add support for Python 3.11 (as of 3.11.0rc1).

  • Switch from -Ofast to -O3 when compiling code for Linux wheels. (#64)

4.10 (2021-12-07)

  • Fix bug in the PURE_PYTHON version affecting aq_acquire applied to a class with a filter.

  • Improve interface documentation.

  • Add support for Python 3.10.

4.9 (2021-08-19)

  • On CPython no longer omit compiling the C code when PURE_PYTHON is required. Just evaluate it at runtime. (#53)

4.8 (2021-07-20)

  • Various fixes for the PURE_PYTHON version, e.g. make Acquired an str (as required by Zope), avoid infinite __cmp__ loop. (#51, #48)

  • Create aarch64 wheels.

4.7 (2020-10-07)

  • Add support for Python 3.8 and 3.9.

4.6 (2019-04-24)

  • Drop support for Python 3.4.

  • Add support for Python 3.8a3.

  • Add support to call bytes() on an object wrapped by an ImplicitAcquisitionWrapper. (#38)

4.5 (2018-10-05)

  • Avoid deprecation warnings by using current API.

  • Add support for Python 3.7.

4.4.4 (2017-11-24)

  • Add Appveyor configuration to automate building Windows eggs.

4.4.3 (2017-11-23)

  • Fix the extremely rare potential for a crash when the C extensions are in use. See issue 21.

4.4.2 (2017-05-12)

  • Fix C capsule name to fix import errors.

  • Ensure our dependencies match our expactations about C extensions.

4.4.1 (2017-05-04)

  • Fix C code under Python 3.4, with missing Py_XSETREF.

4.4.0 (2017-05-04)

  • Enable the C extension under Python 3.

  • Drop support for Python 3.3.

4.3.0 (2017-01-20)

  • Make tests compatible with ExtensionClass 4.2.0.

  • Drop support for Python 2.6 and 3.2.

  • Add support for Python 3.5 and 3.6.

4.2.2 (2015-05-19)

4.2.1 (2015-04-23)

4.2 (2015-04-04)

  • Add support for PyPy, PyPy3, and Python 3.2, 3.3, and 3.4.

4.1 (2014-12-18)

  • Bump dependency on ExtensionClass to match current release.

4.0.3 (2014-11-02)

  • Skip readme.rst tests when tests are run outside a source checkout.

4.0.2 (2014-11-02)

  • Include *.rst files in the release.

4.0.1 (2014-10-30)

  • Tolerate Unicode attribute names (ASCII only). LP #143358.

  • Make module-level aq_acquire API respect the default parameter. LP #1387363.

  • Don’t raise an attribute error for __iter__ if the fallback to __getitem__ succeeds. LP #1155760.

4.0 (2013-02-24)

  • Added trove classifiers to project metadata.

4.0a1 (2011-12-13)

  • Raise RuntimeError: Recursion detected in acquisition wrapper if an object with a __parent__ pointer points to a wrapper that in turn points to the original object.

  • Prevent wrappers to be created while accessing __parent__ on types derived from Explicit or Implicit base classes.

2.13.9 (2015-02-17)

  • Tolerate Unicode attribute names (ASCII only). LP #143358.

  • Make module-level aq_acquire API respect the default parameter. LP #1387363.

  • Don’t raise an attribute error for __iter__ if the fallback to __getitem__ succeeds. LP #1155760.

2.13.8 (2011-06-11)

  • Fixed a segfault on 64bit platforms when providing the explicit argument to the aq_acquire method of an Acquisition wrapper. Thx to LP #675064 for the hint to the solution. The code passed an int instead of a pointer into a function.

2.13.7 (2011-03-02)

  • Fixed bug: When an object did not implement __unicode__, calling unicode(wrapped) was calling __str__ with an unwrapped self.

2.13.6 (2011-02-19)

  • Add aq_explicit to IAcquisitionWrapper.

  • Fixed bug: unicode(wrapped) was not calling a __unicode__ method on wrapped objects.

2.13.5 (2010-09-29)

  • Fixed unit tests that failed on 64bit Python on Windows machines.

2.13.4 (2010-08-31)

  • LP 623665: Fixed typo in Acquisition.h.

2.13.3 (2010-04-19)

  • Use the doctest module from the standard library and no longer depend on zope.testing.

2.13.2 (2010-04-04)

  • Give both wrapper classes a __getnewargs__ method, which causes the ZODB optimization to fail and create persistent references using the _p_oid alone. This happens to be the persistent oid of the wrapped object. This lets these objects to be persisted correctly, even though they are passed to the ZODB in a wrapped state.

  • Added failing tests for http://dev.plone.org/plone/ticket/10318. This shows an edge-case where AQ wrappers can be pickled using the specific combination of cPickle, pickle protocol one and a custom Pickler class with an inst_persistent_id hook. Unfortunately this is the exact combination used by ZODB3.

2.13.1 (2010-02-23)

  • Update to include ExtensionClass 2.13.0.

  • Fix the tp_name of the ImplicitAcquisitionWrapper and ExplicitAcquisitionWrapper to match their Python visible names and thus have a correct __name__.

  • Expand the tp_name of our extension types to hold the fully qualified name. This ensures classes have their __module__ set correctly.

2.13.0 (2010-02-14)

2.12.4 (2009-10-29)

  • Fix iteration proxying to pass self acquisition-wrapped into both __iter__ as well as __getitem__ (this fixes https://bugs.launchpad.net/zope2/+bug/360761).

  • Add tests for the __getslice__ proxying, including open-ended slicing.

2.12.3 (2009-08-08)

  • More 64-bit fixes in Py_BuildValue calls.

  • More 64-bit issues fixed: Use correct integer size for slice operations.

2.12.2 (2009-08-02)

2.12.1 (2009-04-15)

  • Update for iteration proxying: The proxy for __iter__ must not rely on the object to have an __iter__ itself, but also support fall-back iteration via __getitem__ (this fixes https://bugs.launchpad.net/zope2/+bug/360761).

2.12 (2009-01-25)

  • Release as separate package.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

Acquisition-5.1.tar.gz (65.9 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

Acquisition-5.1-cp312-cp312-win_amd64.whl (65.2 kB view details)

Uploaded CPython 3.12Windows x86-64

Acquisition-5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (122.1 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64

Acquisition-5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (122.2 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

Acquisition-5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (114.4 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

Acquisition-5.1-cp312-cp312-macosx_11_0_arm64.whl (64.6 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

Acquisition-5.1-cp312-cp312-macosx_10_9_x86_64.whl (65.3 kB view details)

Uploaded CPython 3.12macOS 10.9+ x86-64

Acquisition-5.1-cp311-cp311-win_amd64.whl (65.1 kB view details)

Uploaded CPython 3.11Windows x86-64

Acquisition-5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (122.3 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64

Acquisition-5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (122.9 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

Acquisition-5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (115.7 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

Acquisition-5.1-cp311-cp311-macosx_11_0_arm64.whl (64.9 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

Acquisition-5.1-cp311-cp311-macosx_10_9_x86_64.whl (65.5 kB view details)

Uploaded CPython 3.11macOS 10.9+ x86-64

Acquisition-5.1-cp310-cp310-win_amd64.whl (65.0 kB view details)

Uploaded CPython 3.10Windows x86-64

Acquisition-5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (118.7 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64

Acquisition-5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (119.4 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

Acquisition-5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (112.3 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

Acquisition-5.1-cp310-cp310-macosx_11_0_arm64.whl (65.0 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

Acquisition-5.1-cp310-cp310-macosx_10_9_x86_64.whl (65.5 kB view details)

Uploaded CPython 3.10macOS 10.9+ x86-64

Acquisition-5.1-cp39-cp39-win_amd64.whl (65.0 kB view details)

Uploaded CPython 3.9Windows x86-64

Acquisition-5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (118.0 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ ARM64

Acquisition-5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (118.7 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

Acquisition-5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (111.7 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

Acquisition-5.1-cp39-cp39-macosx_11_0_arm64.whl (65.0 kB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

Acquisition-5.1-cp39-cp39-macosx_10_9_x86_64.whl (65.5 kB view details)

Uploaded CPython 3.9macOS 10.9+ x86-64

Acquisition-5.1-cp38-cp38-win_amd64.whl (65.0 kB view details)

Uploaded CPython 3.8Windows x86-64

Acquisition-5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (119.1 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ ARM64

Acquisition-5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (119.7 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

Acquisition-5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (112.7 kB view details)

Uploaded CPython 3.8manylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

Acquisition-5.1-cp38-cp38-macosx_11_0_arm64.whl (65.0 kB view details)

Uploaded CPython 3.8macOS 11.0+ ARM64

Acquisition-5.1-cp38-cp38-macosx_10_9_x86_64.whl (65.5 kB view details)

Uploaded CPython 3.8macOS 10.9+ x86-64

Acquisition-5.1-cp37-cp37m-win_amd64.whl (65.0 kB view details)

Uploaded CPython 3.7mWindows x86-64

Acquisition-5.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (109.7 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.17+ ARM64

Acquisition-5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (109.2 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.17+ x86-64manylinux: glibc 2.5+ x86-64

Acquisition-5.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl (102.2 kB view details)

Uploaded CPython 3.7mmanylinux: glibc 2.17+ i686manylinux: glibc 2.5+ i686

Acquisition-5.1-cp37-cp37m-macosx_11_0_x86_64.whl (65.5 kB view details)

Uploaded CPython 3.7mmacOS 11.0+ x86-64

File details

Details for the file Acquisition-5.1.tar.gz.

File metadata

  • Download URL: Acquisition-5.1.tar.gz
  • Upload date:
  • Size: 65.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.3

File hashes

Hashes for Acquisition-5.1.tar.gz
Algorithm Hash digest
SHA256 17e3504b707729cead1a6e70396fce9139802605e71105b5a9774ee578812677
MD5 c33a664347c3283266f45e6755f87063
BLAKE2b-256 6a49af690d6b6a756f5dc42ea38c6466f27f01ea21641f8d220a971f18929a53

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: Acquisition-5.1-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 65.2 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.12.0

File hashes

Hashes for Acquisition-5.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 d054e2e142119e36530d8c5661b800626da1703d93beef1490fb7e7e628e9e16
MD5 e115df2311e4b740dc19551a278a27f0
BLAKE2b-256 d507513b8847a6bed1392086b577fbb6420d40fc14811c1a63d98095d2230f45

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5f702cc947b04b4116d09724786bec9761ef2a7877003448a9934197d0cafa80
MD5 cce598ad84ae91cf83bbb6ea9987b7fd
BLAKE2b-256 8bc7f03bb68e72e09fda97d52743b73cf1a038212aab4ac9067fe5e825d41f6a

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 cccd6c4b0786c2236bf55732ab6e3701dd35a7979a393a9689a89be794ecd490
MD5 ed28d16a4f9a82b26cee5893db14862a
BLAKE2b-256 e5588ef4930fa19dd3dd3413b0ffeceee1f76ce9db7869f273f5f511851317ad

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 743ed98fadf133d1e06b2bd09a9a580ff69ebb78d359cbe8267f36c48536aea8
MD5 e319e4a148580866061b9d3609f6b808
BLAKE2b-256 b5aa5fff66b2eeeae9b923bae142151b003438d2183c902d4d87cfed44f620f1

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 78e3c6c60154f2d1c1c19042ea9d3aa92c5aa4b540a3102ed875f6e60839560d
MD5 95246fa110efe4f42f7c4dc7e368c694
BLAKE2b-256 0d35b56a91167b2e671ec761a54a9ac3692ecd016b00c7ecd1706afd2c28bdf0

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp312-cp312-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp312-cp312-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 6515597e84da9f38fa894a3bc30b2a693a6218d68babb5ff0177f46709120a48
MD5 4d44b10e98b1b62f237e1c7fca6619c8
BLAKE2b-256 2c1bcd9b2a38971019be314ccb61bb8210b0f4f69630444c2d82fdda113efcdd

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: Acquisition-5.1-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 65.1 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.0

File hashes

Hashes for Acquisition-5.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 98a3873eac0aef3546b3af535fc93c3f770a6c35f14107133d30de102d48f02a
MD5 f4c7bb7151b2923f7244d385fbf23930
BLAKE2b-256 9af0cbd8da3354d0d2b22ea10846ab1e24e4457a3a2edcf6c1b63cc3dfe784b3

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e6a66645139a346d58adc1b6ac34c6f405c83a9fee9569915aff5df88175ce64
MD5 26e9ab8439917c8dd3c30597784818a4
BLAKE2b-256 efce58bba287939363e7888eb3e24f69d3dae60b068b9d7da4df21acd3d04046

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 925ed9f9facb4c6da04194b02ff9a7030bd465ed6d0f5c908ca0ab7173c7a2c8
MD5 cfbabd2cf08a1bd1697ae34a29c294ab
BLAKE2b-256 8a29fc84fd74aee1d4612a564044476c567d0d422dd3515f9f67f0594011efc3

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 496625f1bad767c54f83a0eb99163c943252c06e4a8269b151cd4fefb348e6c3
MD5 d4de33ba9a50a8c4e58e2b7448b48015
BLAKE2b-256 873a544f067ceaf348f78d840950f5e82db6a2601a1c4f9be21b5a8ed17a711b

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 6e1e4916c3bd3429ab8ddb85b4bc7a3e68f00980065cee802ff62a93ae8bcce9
MD5 2997fef9574f13d0f6acd4f21d36df9b
BLAKE2b-256 6436857983b4995f2886185e5cde2eee70da1b6f8e2080d122bb5efbcf0c2f89

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 bac53bfa39efdab85cebcf7e863e6543b03d3abcf9208211b5ce3d623bdf8a0a
MD5 48de8b8895f15dc415490f49418e1132
BLAKE2b-256 49a261b894ddaa95240e903b211d76c60eb7a2e679dab0f9a43a724c55b56cc4

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: Acquisition-5.1-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 65.0 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.0

File hashes

Hashes for Acquisition-5.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 375e581f2a242054ad8d8ecf6865fde5fa611ee8778441e769efdfa300e83211
MD5 9f11cfac51689e0872eeb6884b10dfcc
BLAKE2b-256 8b7f29aece98ea7bd1896a7d8d221e2890d073880aacea545f7aa08ad3f88b48

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 59038f884b7c09f9caa57d63e5ac21f979a84ca4dd5cd6aad0c57ac7ceabab34
MD5 7ad92d5099892b3f7164a9dc2d33baa9
BLAKE2b-256 5b0f7d803a9433de9409c721f08bfc08497fcf1fec063a08798a7178f16b2cae

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a3c834960f70182708e0f916012a6498080419780fc4539493bd6dd4d27310b2
MD5 dd16c242b19d5c3dbd9cbcdfbfb6366a
BLAKE2b-256 91acae205354ac767bc32c16fba2ce402d9d9d3f8ce5bd7dfd98eb31f47e02a6

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 66984a3ae8d1a280bbf42c8d430ef31ae57c07492d303957e3c5b38528d8b637
MD5 470868871c1097b2423733c6f10829de
BLAKE2b-256 cc08bf647699b5bf427b7cd136a8dd2f2c33387a514548bc1e367ae0177db26a

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c5cd8c8e168778606d81a3621912585b06962c9e81b60476a2526f74e61aa12a
MD5 8bfeeb83494dd562471481885a458879
BLAKE2b-256 3b34bcc27029513d478c1da121129779c85df97cbd474258fc25be9b303edc5d

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 06e54b67a3166e684257c577f4a5fe0f7fd8f1cf344e0bf4efe78a7a9b4705b8
MD5 a4bcdac6d7275c0d7affd7096d470756
BLAKE2b-256 996706490e738effd7883c4ec5f1160d4416a9647d8c5d7182327eb90c8357cc

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: Acquisition-5.1-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 65.0 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.0

File hashes

Hashes for Acquisition-5.1-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 699cdfc30c748f9b0d301f149b8816387a847a06b778dbfa573cb8fa2d2135d3
MD5 151e9d2b078ec5a4428e65a5a416dc38
BLAKE2b-256 39d49d7b9ef317d9c3749dafae655b66652993ea86760a1445716985bf7fd6f9

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6fc9bdb858ec3c50b5eadd0a8656574853ed7b766087cabbc5b7021bfe40f640
MD5 b4552b00b5d3dea152b0629e5c53fbe3
BLAKE2b-256 8bfd7edf2cb17f3dfc4f69cbabc387d2f72a1a59c02eeea1a9b8acc290ca5f6e

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 397c4927a0fee97c62ec8dfbf295d9f42675d0ffb4b771e0cc08a65e1220492c
MD5 558c4742bdea349bdc3705c7938049b7
BLAKE2b-256 177f4bd1f9d89b17df759a0fbf5ffcf9ff10392505826824ea5df90981459db8

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 d24bac45c6adc17d9da6f25efb36570655e7750d68019228f6d4705b5d7746f9
MD5 6a1e27e19dba1596aa86961c257b60ee
BLAKE2b-256 f41f0847c7ac454de712f2849c3ef39337f486778e1582555c0e1547b2d4ac23

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8da8eb0a19355fd0f3aac5dc5eb1a8b350e6c787862faaab2801da9f78fefb71
MD5 38d9b88b2e67d6e30b0e941e274abe36
BLAKE2b-256 817dcdf20a697d56b03e7cdf8a338655ec6a605b85e8078b60692a241dec429b

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp39-cp39-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp39-cp39-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 32d971f85facab87016a9827939a44d92b4245d155bc4b741e642d4bc03ab44b
MD5 dac72de1eb9c828687767aa0b759558b
BLAKE2b-256 5a581033bd7397277f656bbffe1fbe348f4752c2fe775d3bb1f72e046e4cfd86

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp38-cp38-win_amd64.whl.

File metadata

  • Download URL: Acquisition-5.1-cp38-cp38-win_amd64.whl
  • Upload date:
  • Size: 65.0 kB
  • Tags: CPython 3.8, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.8.0

File hashes

Hashes for Acquisition-5.1-cp38-cp38-win_amd64.whl
Algorithm Hash digest
SHA256 043c186da1c174fe711e45de78abf1d98fec7f3c02bbd803fe1aceead32d546c
MD5 a9bf799ac0f813e645086e9e4be931fd
BLAKE2b-256 9147c128b1c86435749a4a5820c08785435fbc616b74f98af6b8e4fd2be0a3ac

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0b9209e6d86ba78b90fc1044c4b7de982dd07c957a63c72cf8b1f0b2dba12d7d
MD5 b66c477d87502d9726af632e9c7f3f65
BLAKE2b-256 2c29e226c45487881c304775625f14df6b3d436f3785edd0a28683aeba98b632

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a009abe92f770091b5904f22dffc9518496a63a88cae695dac4ee54e0f9d6c11
MD5 5eb8fbcc12e568a81ebca6ca8ceba94c
BLAKE2b-256 4678c2d210390de53cd3beec52813bee668e4239f638e25d8c57665b4ce8480d

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 562c526a8eeed86a51652f4953e4c6c3f32c5445c85d0fb3c12c6162d392c260
MD5 ea438f3af2804559b675df94b54dc52b
BLAKE2b-256 7f2fe4426df9c6776fdf46be6c653c2ee176541a99da374fd66dcc13de11a7d0

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp38-cp38-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp38-cp38-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 c028a13c20a5b72ce21460c2763ab90f7d6c28dea7e995fd5879b70595f25ad4
MD5 20f98fb28e30e799d7e24b3437b38e3c
BLAKE2b-256 8381978a5de27d6253b90c5a646516f6d8c7a7af97b4f8b95b6b843a58559ede

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp38-cp38-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp38-cp38-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 696b2e7573e34c4b639371793d4a27d9c3a03051b7294400f4d789db3ff381c6
MD5 6a649f46ff48d6ba66df0587fe6df81f
BLAKE2b-256 527911c87e1e7f3edc9e3aeac102ffc10ffc4f9e1d56ce5129c02b1fc4ac2e1a

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp37-cp37m-win_amd64.whl.

File metadata

  • Download URL: Acquisition-5.1-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 65.0 kB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.7.5

File hashes

Hashes for Acquisition-5.1-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 13e89516f29db9b0107654a70a1ca7da071e90dda1bbce0a9ff5f3d883717fae
MD5 86af868e748621d9a88531610db45625
BLAKE2b-256 185517e4f884a3d50abd3b0c3285cf4555840fc6f23f1c1b626003a30cd98650

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 885fbf90b6189f86307c67134b6a67c1c8666323367f28e74a2e0cf3e5df7b23
MD5 77741dd0c016d4e8de46802933b93cbc
BLAKE2b-256 638903dacca152c42bb246ba3dac31106829ccda2b40edf118f8c665943b7556

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 d78a3006a388d567516a954552a9ed3b4f12e884c5c005c00a2603406aee3793
MD5 8272f51e49eb0e87edb8383cc322984f
BLAKE2b-256 21b05758b580aeb82140a27bd5a0536fcb7b6c573ceb6f9b09a9b5a206031f04

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 a77458eebad29f8836a2f9becfea78719352de3bcc00753c9ede6b160d77fc68
MD5 3cfc17b0af19bf42ae6c9b8c440da11e
BLAKE2b-256 bcb20930a4c55e0210bd6b6a431b2f46156d944cf8f1839869f5748b675b5aed

See more details on using hashes here.

File details

Details for the file Acquisition-5.1-cp37-cp37m-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-5.1-cp37-cp37m-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 01457ef5bfd9c88da0a20ba3061845c461025197f874b347d2a3d300070bd278
MD5 6bf8c84dae2e6744ad8fa1b1c947f081
BLAKE2b-256 017475bb036bc72be4f6f0fdc3884cbbc188460057f43cde20fd14de28daa0d2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page