1. Michał Górny
  2. gentoopm
Issue #4 new

inconsistent hash values for dependencies

Burcin Erocal
created an issue

The classes representing dependencies do not implement a consistent __hash__ method. This causes problems when trying to get all dependencies of a package using set unions for instance:

In [1]: import gentoopm

In [2]: pm = gentoopm.get_package_manager()

In [3]: gentoo = pm.repositories['gentoo']

In [4]: gnutls = gentoo.select('=gnutls-2.12.20')

In [5]: s = set(gnutls.build_dependencies)

In [6]: u = s.union(set(gnutls.run_dependencies))

In [7]: u
Out[7]: 
{PaludisAnyOfDep(
    PaludisAtom('>=sys-devel/automake-1.12:1.12'),
    PaludisAtom('>=sys-devel/automake-1.13:1.13')),
 PaludisAtom('>=dev-libs/libtasn1-0.3.4'),
 PaludisAtom('<dev-libs/libtasn1-3'),
 PaludisAtom('virtual/pkgconfig'),
 PaludisAtom('sys-devel/libtool'),
 PaludisAtom('>=sys-devel/autoconf-2.68'),
 PaludisConditionalDep(
    PaludisAtom('>=dev-libs/nettle-2.1[gmp]')),
 PaludisConditionalDep(
    PaludisAtom('>=dev-scheme/guile-1.8[networking]')),
 PaludisConditionalDep(
    PaludisAtom('>=dev-libs/libgcrypt-1.4.0')),
 PaludisConditionalDep(
    PaludisAtom('virtual/libintl')),
 PaludisConditionalDep(
    PaludisAtom('>=app-crypt/p11-kit-0.11')),
 PaludisConditionalDep(
    PaludisAtom('>=sys-libs/zlib-1.2.3.1')),
 PaludisConditionalDep(
    PaludisConditionalDep(
        PaludisAtom('>=dev-libs/lzo-2'))),
 PaludisConditionalDep(
    PaludisAtom('dev-util/gtk-doc')),
 PaludisConditionalDep(
    PaludisAtom('sys-devel/gettext')),
 PaludisConditionalDep(
    PaludisAtom('app-misc/datefudge')),
 PaludisConditionalDep(
    PaludisAtom('>=dev-libs/nettle-2.1[gmp]')),
 PaludisConditionalDep(
    PaludisAtom('>=dev-scheme/guile-1.8[networking]')),
 PaludisConditionalDep(
    PaludisAtom('>=dev-libs/libgcrypt-1.4.0')),
 PaludisConditionalDep(
    PaludisAtom('virtual/libintl')),
 PaludisConditionalDep(
    PaludisAtom('>=app-crypt/p11-kit-0.11')),
 PaludisConditionalDep(
    PaludisAtom('>=sys-libs/zlib-1.2.3.1')),
 PaludisConditionalDep(
    PaludisConditionalDep(
        PaludisAtom('>=dev-libs/lzo-2')))}

In [8]: for t in u: print t, hash(t)
PaludisConditionalDep(
    PaludisAtom('>=sys-libs/zlib-1.2.3.1')) 2680385
PaludisConditionalDep(
    PaludisAtom('>=dev-scheme/guile-1.8[networking]')) 2680369
PaludisConditionalDep(
    PaludisAtom('dev-util/gtk-doc')) 2680325
PaludisConditionalDep(
    PaludisAtom('sys-devel/gettext')) 2680329
PaludisConditionalDep(
    PaludisAtom('app-misc/datefudge')) 2680333
sys-devel/libtool 6791675545220144785
PaludisConditionalDep(
    PaludisAtom('>=dev-libs/nettle-2.1[gmp]')) 2680361
PaludisConditionalDep(
    PaludisAtom('virtual/libintl')) 2680377
PaludisConditionalDep(
    PaludisAtom('>=dev-libs/nettle-2.1[gmp]')) 2529753
PaludisConditionalDep(
    PaludisAtom('>=dev-libs/libgcrypt-1.4.0')) 2680373
<dev-libs/libtasn1-3 -8783740539733868323
PaludisConditionalDep(
    PaludisConditionalDep(
        PaludisAtom('>=dev-libs/lzo-2'))) 2680389
PaludisConditionalDep(
    PaludisAtom('>=dev-scheme/guile-1.8[networking]')) 2529761
PaludisConditionalDep(
    PaludisAtom('>=dev-libs/libgcrypt-1.4.0')) 2529765
PaludisAnyOfDep(
    PaludisAtom('>=sys-devel/automake-1.12:1.12'),
    PaludisAtom('>=sys-devel/automake-1.13:1.13')) 2680337
PaludisConditionalDep(
    PaludisAtom('virtual/libintl')) 2529769
PaludisConditionalDep(
    PaludisAtom('>=app-crypt/p11-kit-0.11')) 2529773
PaludisConditionalDep(
    PaludisAtom('>=sys-libs/zlib-1.2.3.1')) 2529777
>=dev-libs/libtasn1-0.3.4 8678660166895615669
virtual/pkgconfig 4469295218190311177
>=sys-devel/autoconf-2.68 1525087095887007737
PaludisConditionalDep(
    PaludisAtom('>=app-crypt/p11-kit-0.11')) 2680381
PaludisConditionalDep(
    PaludisConditionalDep(
        PaludisAtom('>=dev-libs/lzo-2'))) 2529781

Comments (5)

  1. Burcin Erocal reporter

    Sure. But I cannot wrap my head around the current design of the dependency API.

    It seems to be a thin layer on top of the classes provided by the package managers, which I am not familiar with. In order to get any real information out of the dependency classes, such as the name of the package, the user has to deal with the corresponding package manager directly.

    This would mean implementing a hash function and equality test for each class for each package manager. Perhaps using portage directly is better in this case.

  2. Burcin Erocal reporter

    Yes, string based hashes as in this patch work, but this is a hack.

    Wouldn't it be better to convert the dependency information obtained from the package manager into the gentoopm classes defined in basepm/depend.py? This would mean making these classes less abstract of course.

  3. Michał Górny repo owner

    Oh, wait, those dependencies don't get stringified properly. And atoms themselves have hash() method defined already. I think I missed your point.

    Well, the thing you did is a hack indeed but it'll probably mostly work. However, hashing whole dependency sets properly is impossible at the point, for the simple reason that PMs don't provide us with all the required data. Paludis is especially painful in this regard, with many information hidden as private, and many of the remaining properties not wrapped in Python API.

  4. Log in to comment