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

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-4.6.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-4.6-cp37-cp37m-win_amd64.whl (64.7 kB view details)

Uploaded CPython 3.7mWindows x86-64

Acquisition-4.6-cp37-cp37m-win32.whl (62.4 kB view details)

Uploaded CPython 3.7mWindows x86

Acquisition-4.6-cp36-cp36m-win_amd64.whl (64.7 kB view details)

Uploaded CPython 3.6mWindows x86-64

Acquisition-4.6-cp36-cp36m-win32.whl (62.4 kB view details)

Uploaded CPython 3.6mWindows x86

Acquisition-4.6-cp35-cp35m-win_amd64.whl (64.7 kB view details)

Uploaded CPython 3.5mWindows x86-64

Acquisition-4.6-cp35-cp35m-win32.whl (62.4 kB view details)

Uploaded CPython 3.5mWindows x86

Acquisition-4.6-cp34-cp34m-win32.whl (61.0 kB view details)

Uploaded CPython 3.4mWindows x86

Acquisition-4.6-cp27-cp27m-win_amd64.whl (62.7 kB view details)

Uploaded CPython 2.7mWindows x86-64

Acquisition-4.6-cp27-cp27m-win32.whl (61.3 kB view details)

Uploaded CPython 2.7mWindows x86

File details

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

File metadata

  • Download URL: Acquisition-4.6.tar.gz
  • Upload date:
  • Size: 65.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.10.0 pkginfo/1.4.2 requests/2.18.4 setuptools/39.0.1 requests-toolbelt/0.8.0 tqdm/4.19.7 CPython/2.7.16

File hashes

Hashes for Acquisition-4.6.tar.gz
Algorithm Hash digest
SHA256 dcb318066c3f295b557f79a2e740302edb298f42d62123ffa6e328d79287218e
MD5 a97dd3880597e84e901c21e9859fec7f
BLAKE2b-256 9fd436228e04dc08be90e6b9b71707345c8ab2fe02c92d966254e020966856cd

See more details on using hashes here.

File details

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

File metadata

  • Download URL: Acquisition-4.6-cp37-cp37m-win_amd64.whl
  • Upload date:
  • Size: 64.7 kB
  • Tags: CPython 3.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.3

File hashes

Hashes for Acquisition-4.6-cp37-cp37m-win_amd64.whl
Algorithm Hash digest
SHA256 265bff224f01df1db59f4709ec8f34ac1744bf53b6c9d7bb9c336cf7bdaf02f9
MD5 1e0e8c6eca7d90a26fdd19c9f1afb0ca
BLAKE2b-256 83967b33b171e7e3b05061073320713935be2062268e2767f95924b0bb3e54a6

See more details on using hashes here.

File details

Details for the file Acquisition-4.6-cp37-cp37m-win32.whl.

File metadata

  • Download URL: Acquisition-4.6-cp37-cp37m-win32.whl
  • Upload date:
  • Size: 62.4 kB
  • Tags: CPython 3.7m, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.7.3

File hashes

Hashes for Acquisition-4.6-cp37-cp37m-win32.whl
Algorithm Hash digest
SHA256 7ff9056f94c715215bacdd1a3d8fc58a3aa3221d65ee05c32911a40c6e0e6785
MD5 f737226e8daf7e6b03326916e1835a72
BLAKE2b-256 10c3af998af3bdd94093f2fee568a36fa37edd592e64d7fc9f9c769872a1368a

See more details on using hashes here.

File details

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

File metadata

  • Download URL: Acquisition-4.6-cp36-cp36m-win_amd64.whl
  • Upload date:
  • Size: 64.7 kB
  • Tags: CPython 3.6m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.8

File hashes

Hashes for Acquisition-4.6-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 7a91fdbe7f16b13dcec57fdb2cde390760a5534db0c7742a0c2605e298fa46a4
MD5 24e866819720b47183c8d2a9c2fa0d17
BLAKE2b-256 10c596a61d23abb730bbaa02060fe9bad8dfeb7979e605ebb966daef04aeac22

See more details on using hashes here.

File details

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

File metadata

  • Download URL: Acquisition-4.6-cp36-cp36m-win32.whl
  • Upload date:
  • Size: 62.4 kB
  • Tags: CPython 3.6m, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.8

File hashes

Hashes for Acquisition-4.6-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 07fc07841ddbed9f27c95b2495956fedec0c4b4e9a3bf1742861f8f5ca263069
MD5 452e21b805305a503fd8ee7cbf0a43a3
BLAKE2b-256 8dda7b078c547be37f2a1a81960c0ee34cde75f97bb5adadab2223139901a126

See more details on using hashes here.

File details

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

File metadata

  • Download URL: Acquisition-4.6-cp35-cp35m-win_amd64.whl
  • Upload date:
  • Size: 64.7 kB
  • Tags: CPython 3.5m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.5.4

File hashes

Hashes for Acquisition-4.6-cp35-cp35m-win_amd64.whl
Algorithm Hash digest
SHA256 8fc32e5a6284b1b027ae93fceecdf65806d06600d4a79cb2b75360e13ade9ceb
MD5 4e1eff30e972a6338d9826d3b0729c71
BLAKE2b-256 6239328d8c413563dce56485e896cffe6af110ef5d3a574aa1f4b3da781d9ea5

See more details on using hashes here.

File details

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

File metadata

  • Download URL: Acquisition-4.6-cp35-cp35m-win32.whl
  • Upload date:
  • Size: 62.4 kB
  • Tags: CPython 3.5m, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.5.4

File hashes

Hashes for Acquisition-4.6-cp35-cp35m-win32.whl
Algorithm Hash digest
SHA256 cf09a19c76d3fe0db576980321ef14b841dc5ea5f80132c9bf6e54f00714b7e1
MD5 936d44460bc01072b3d3b0d53aa4bc5f
BLAKE2b-256 66928a7bc6d2c97418460f7abc8affae9b37339cf42f1d418344ff3a8bce7513

See more details on using hashes here.

File details

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

File metadata

  • Download URL: Acquisition-4.6-cp34-cp34m-win32.whl
  • Upload date:
  • Size: 61.0 kB
  • Tags: CPython 3.4m, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.4.4

File hashes

Hashes for Acquisition-4.6-cp34-cp34m-win32.whl
Algorithm Hash digest
SHA256 4431efb4cf0c766d8d121f64ac97579569b491722e71a634b1be6cc231f7b3fa
MD5 b9b50dc3d013884c2f0849291edb64af
BLAKE2b-256 1cc3e5927e7223fe4a44ad938212926e469671c512ae5b8353529aeec8dd89c6

See more details on using hashes here.

File details

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

File metadata

  • Download URL: Acquisition-4.6-cp27-cp27m-win_amd64.whl
  • Upload date:
  • Size: 62.7 kB
  • Tags: CPython 2.7m, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/2.7.16

File hashes

Hashes for Acquisition-4.6-cp27-cp27m-win_amd64.whl
Algorithm Hash digest
SHA256 440e25d89ad422352fa9f5f1f30d01528c0237ae59f71a7441e21ef5cb05a58f
MD5 2d3fe330b863c1d867264aef333b732c
BLAKE2b-256 33abfd912065a686ccb413d453aae0429053f98ebf059d24bc8cd9771eca1ddb

See more details on using hashes here.

File details

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

File metadata

  • Download URL: Acquisition-4.6-cp27-cp27m-win32.whl
  • Upload date:
  • Size: 61.3 kB
  • Tags: CPython 2.7m, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.21.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/2.7.16

File hashes

Hashes for Acquisition-4.6-cp27-cp27m-win32.whl
Algorithm Hash digest
SHA256 a687ec005597ec2dd257c6fdd611d3a459e05e460f0f859599c4f4c00c9663af
MD5 a60218db1f0d5b2fe5fab836b93e024c
BLAKE2b-256 5824bd3d026bc98b1fccbc01825b7738883ddc398a66c595831163608bf7fb9c

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