-2

I have this method:

def filter_branches_by_names(self, names, exclude=False):
    """Filter branches list using names list.

    Args:
        names (list): names list to use as
            filter condition.
        exclude (bool): If set to False, keep branches in
            names list. If set to True, keep branches not in names
            list. Optional, default: False.
    Returns:
        branch (list): list of git branch objects.
    """
    heads = self.repo.heads
    if exclude:
        return [head for head in heads if head.name not in names]
    else:
        return [head for head in heads if head.name in names]

It filters out branch objects that are accessed using gitPython library. I do not know if that is something special with library (or it works for all objects), but when I use sorted on result of that function, it actually does not sort those objects.

I mean this does not work:

sorted(self.filter_branches_by_names(['a', 'b'])

This works:

sorted(self.filter_branches_by_names(['a', 'b'], key=lambda x: x.name)

I'm using sorted for my unittests to check if I get correct branches when using that method, so I actually do not care how it is sorted, as long as both result and compared against lists are sorted the same.

So is sorted intended to not sort objects (I thought it uses some kind of default parameter to sort by) when not specifying key or it is something else here?

NOTE: I'm not saying I'm expecting it to sort by name attribute. What I'm saying it does not sort at all, when not specifying key for sorted. It seems people misunderstood me.

Andrius
  • 19,658
  • 37
  • 143
  • 243
  • 2
    Sure it is, but how should Python know that you want to sort by the `name` attribute instead of by the natural ordering of the objects? See [rich comparison methods](https://docs.python.org/3/reference/datamodel.html#object.__lt__). – Phillip May 15 '17 at 19:14
  • 1
    If you don't supply a key or comparator function, `sorted()` will use the object's own definition of comparison. Perhaps these git branch objects you're using define comparison with something other than the `name` field as the primary key, perhaps they don't define comparison at all. – jasonharper May 15 '17 at 19:14
  • @jasonharper I guess it does not have comparison defined, cause it should have sorted by something then. – Andrius May 15 '17 at 19:19
  • @Phillip You did not understood my question I guess. I did not say it should sort by name. What I said it did not sort by anything when not specifying key. I do not care by what it sorts, as long it sorts. – Andrius May 15 '17 at 19:20
  • ["If no `__cmp__()`, `__eq__()` or `__ne__()` operation is defined, class instances are compared by object identity (“address”)."](https://docs.python.org/2/reference/datamodel.html#object.__cmp__) – TemporalWolf May 15 '17 at 19:24
  • @TemporalWolf but shouldn't it still sort if it compares `address`, assuming objects are the same? – Andrius May 15 '17 at 19:26
  • They are presumably sorted in the order they were created, which is the order they are currently in: whatever order gitPython generates the objects. – TemporalWolf May 15 '17 at 19:28
  • @TemporalWolf it seems there are different objects I'm comparing against. I mean result I get have different objects than the ones I was comparing against. Though it is kind of strange, cause I'm accessing both from same instance. So it was actually sorting, but because objects are different it was sorting those objects differently. – Andrius May 15 '17 at 19:33

2 Answers2

0

The problem was not with sorted, the problem was that every time branches are accessed from gitPython repo instance, it actually creates new branch object, so it sorts two lists with (kind of same branches) branches differently (using identity address), because those objects are different.

Though, if they are sorted by let say name (name is the same even if new branch object is created), then it passes assertEqual check, even if those objects are different.

Andrius
  • 19,658
  • 37
  • 143
  • 243
0

The base class object defines all 6 rich comparison methods: __eq__, __ge__, __gt__, and so on. These default methods compare by integer object identity, as returned by id(obj). For most purposes, one may consider ids to be random unique integers. Any class can define more appropriate comparison methods for instances of the class. It appears that the branch object class does not. My guess is that the authors of the class expect you to select an attribute for sorting.

Terry Jan Reedy
  • 18,414
  • 3
  • 40
  • 52