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. Your 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 2 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

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)

  • Fixed 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-4.4.4.tar.gz (64.4 kB view details)

Uploaded Source

Built Distributions

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

Acquisition-4.4.4-cp36-cp36m-win_amd64.whl (71.7 kB view details)

Uploaded CPython 3.6mWindows x86-64

Acquisition-4.4.4-cp36-cp36m-win32.whl (69.4 kB view details)

Uploaded CPython 3.6mWindows x86

Acquisition-4.4.4-cp36-cp36m-manylinux1_x86_64.whl (115.6 kB view details)

Uploaded CPython 3.6m

Acquisition-4.4.4-cp35-cp35m-win_amd64.whl (71.7 kB view details)

Uploaded CPython 3.5mWindows x86-64

Acquisition-4.4.4-cp35-cp35m-win32.whl (69.4 kB view details)

Uploaded CPython 3.5mWindows x86

Acquisition-4.4.4-cp35-cp35m-manylinux1_x86_64.whl (115.6 kB view details)

Uploaded CPython 3.5m

Acquisition-4.4.4-cp34-cp34m-win_amd64.whl (69.4 kB view details)

Uploaded CPython 3.4mWindows x86-64

Acquisition-4.4.4-cp34-cp34m-win32.whl (68.0 kB view details)

Uploaded CPython 3.4mWindows x86

Acquisition-4.4.4-cp34-cp34m-manylinux1_x86_64.whl (115.2 kB view details)

Uploaded CPython 3.4m

Acquisition-4.4.4-cp33-cp33m-win_amd64.whl (69.4 kB view details)

Uploaded CPython 3.3mWindows x86-64

Acquisition-4.4.4-cp33-cp33m-win32.whl (68.0 kB view details)

Uploaded CPython 3.3mWindows x86

Acquisition-4.4.4-cp27-cp27mu-manylinux1_x86_64.whl (113.9 kB view details)

Uploaded CPython 2.7mu

Acquisition-4.4.4-cp27-cp27m-win_amd64.whl (69.7 kB view details)

Uploaded CPython 2.7mWindows x86-64

Acquisition-4.4.4-cp27-cp27m-win32.whl (68.2 kB view details)

Uploaded CPython 2.7mWindows x86

Acquisition-4.4.4-cp27-cp27m-manylinux1_x86_64.whl (113.9 kB view details)

Uploaded CPython 2.7m

File details

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

File metadata

  • Download URL: Acquisition-4.4.4.tar.gz
  • Upload date:
  • Size: 64.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for Acquisition-4.4.4.tar.gz
Algorithm Hash digest
SHA256 dd460343deec47bbbe4f1bce50fee595ab42eecdfd4372678cc472b640540126
MD5 9524b854ec5c13c779a898a7e2d149cb
BLAKE2b-256 c1b3ae140401dac7400f18481481a5ede99c137d5a787f64eb0e6ccc66f810cd

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp36-cp36m-win_amd64.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 b7c43c21eb77f3d4ba4a49d886e9e48daa8fb8bf4bbb25986038d7afc935ea46
MD5 b79c2c0a82898485554e7b599b3564cd
BLAKE2b-256 0bb869fcddecbee5c3442fe904b20deb0f4b06f9fe0f8f6e9c6bcdb72def18b7

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp36-cp36m-win32.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 b59bf0aa7a65adb9b022252831e0dc73920527ab1c15008051fc5dd1a88566e5
MD5 4ec4b18af2dbb54fecea5e0de0583752
BLAKE2b-256 00bcadab0b088256ae17f59b84ec425259c6b791cea44c4e847cbaa5acac9d82

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp36-cp36m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 0497abb360cd9027e3f26b0d0c4c301a0e190abb6406644696310a2b4570c1af
MD5 dd53cc87a1c0901d367553594ccc0b73
BLAKE2b-256 26f80899f1671cd59eca96dda9562379d1240e6a3fdaf33b487d0bfa09e45cc1

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp35-cp35m-win_amd64.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp35-cp35m-win_amd64.whl
Algorithm Hash digest
SHA256 cfc6612453ba1a7a881b240846da72b0b4a45ee7118993beaf2188f9056ae4ea
MD5 14c2cdbc5707bae865f4458d27cea3c8
BLAKE2b-256 f522ceee7e7d8912511d8085365fd1616ffd45dbc45c06bb881549390c4b9d15

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp35-cp35m-win32.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp35-cp35m-win32.whl
Algorithm Hash digest
SHA256 a1cd3cff625af3b683731c563f407473dbeb22c198eaa0d762eeee119f021a83
MD5 de20c058bc7f8b57df2291d66d188f2c
BLAKE2b-256 21e28ef3c60f663d565a6f610b1c26ea4e0919c2756feae64087d2151269b8f9

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp35-cp35m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp35-cp35m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 eafcbf1d7d62dab28f7c6c560c6a84ee037ccff1c65dff0a9dc97d54ea07e23e
MD5 7ce406e576fde76e852cb15f4da8062f
BLAKE2b-256 91fbfd2f841d9aced2dd58819881e367c57f603f97fd5978528b38b1e8eefa41

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp34-cp34m-win_amd64.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp34-cp34m-win_amd64.whl
Algorithm Hash digest
SHA256 dc5c9c4c91d0f7b68907ad19d5471e913b9a634314f25f49a5b88844580778e8
MD5 29c77f55a0ba821f4eba0c985ac3616a
BLAKE2b-256 2f757e85af311e0553e224dfe0eaccfb013b3ef5a752c05f45f9d613552059cb

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp34-cp34m-win32.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp34-cp34m-win32.whl
Algorithm Hash digest
SHA256 4d5029cf0273c25d4c07cda8a4eb51519bd71c51e1040a5c87eebcb844dcb171
MD5 f8b23b83b7a08493d2523ae828df4d03
BLAKE2b-256 57a7b86c651d64d0148ce7a589e0875e50a8d1e181a42a33618afc55096092e6

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp34-cp34m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp34-cp34m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 427944f712b74111ab7b69a461b4fde45c2322da151dec5414a13640ec82cae7
MD5 ef65323e627048187dfda92448511997
BLAKE2b-256 6212b0c1d6eb9916bccf2b7b34f1b2a291dbca5bf958049190ff07cfaf684a8d

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp33-cp33m-win_amd64.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp33-cp33m-win_amd64.whl
Algorithm Hash digest
SHA256 82b47356b389a19867ef996fee150f4f0ded7d53e0cb170ba7e97aaabb788d39
MD5 43b1a499da3149868a79a465361a01f8
BLAKE2b-256 7731f5ffdfad5d9c69fbd359cc062b8ced0db88e2cf6f7a6e6ae1ad29e81abcd

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp33-cp33m-win32.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp33-cp33m-win32.whl
Algorithm Hash digest
SHA256 cfe6647dc132b5a92866433aa17c22a947d8eb11d715d70775891af3c7877e5c
MD5 5fded22c0b3dba3dafdafc796ba6b09d
BLAKE2b-256 13c715c4967cc9e55e3fab31e64b2a35bc652c53636f7efa69a53baaff0240d9

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp27-cp27mu-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp27-cp27mu-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 c567ca822d198deae57ce9ead5bd2af01d84daf7aac9ecc52bcb2905c9cd19dd
MD5 4d5ec04d5b2e82ba4f38f058cc1efcb7
BLAKE2b-256 72eb2c5d15b6667025f2b35527237e3a3bf016ecd6f0574014cb2cc72849885f

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp27-cp27m-win_amd64.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp27-cp27m-win_amd64.whl
Algorithm Hash digest
SHA256 dd56099a9fefcc8816bf8100284dc9a2b6b69ea4c7c5dab40efd9c79208c7811
MD5 e2f8ae0902933c2810e2ce2e45af140e
BLAKE2b-256 6a3fc6a42c279f6c1a70a0f2b67b61d6021fa3820b302a3f9710a0e62279f743

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp27-cp27m-win32.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp27-cp27m-win32.whl
Algorithm Hash digest
SHA256 898e265534d9d53dca69545fa1c379a47d3416f2f7e0e1001aba9ed720dc2bfe
MD5 e16d438f4d435c1183c804d492eac82c
BLAKE2b-256 2ad8bc0ea0c151cf6ea8b8e1d585548071ca578c3affb9452f72c49e28e7e94c

See more details on using hashes here.

File details

Details for the file Acquisition-4.4.4-cp27-cp27m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for Acquisition-4.4.4-cp27-cp27m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 e195883ce3018aab24691af25858e32c7759a66fb7e1088f1043740095d56eb7
MD5 5da3c01dbc1de242eda988f161232d53
BLAKE2b-256 b6ad362528e390d47c8198ac967cf5488494931e7ac1715e0a5bed7fbfe57f2f

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