Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get rid of more references to __cmp__ #46058

Closed
gvanrossum opened this issue Jan 1, 2008 · 92 comments
Closed

Get rid of more references to __cmp__ #46058

gvanrossum opened this issue Jan 1, 2008 · 92 comments
Assignees
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@gvanrossum
Copy link
Member

BPO 1717
Nosy @malemburg, @brettcannon, @birkenfeld, @rhettinger, @amauryfa, @mdickinson, @pitrou, @tiran, @benjaminp, @septatrix
Dependencies
  • bpo-4704: Update pybench for python 3.0
  • Files
  • nocmp.diff
  • nocmp_tests.diff: Fixes for failing tests
  • remove_cmp_decimal.patch: Fix cmp in decimal module and tests
  • remove_cmp2.patch
  • remove_cmp3.patch
  • remove_cmp4.patch
  • remove_cmp5.patch
  • remove_cmp6.patch
  • 1717_stage1.patch
  • 1717_stage1_v2.patch
  • 1717_stage2.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/birkenfeld'
    closed_at = <Date 2009-03-31.18:56:48.551>
    created_at = <Date 2008-01-01.16:39:25.550>
    labels = ['interpreter-core', 'type-bug']
    title = 'Get rid of more references to __cmp__'
    updated_at = <Date 2021-05-26.19:36:09.236>
    user = 'https://github.com/gvanrossum'

    bugs.python.org fields:

    activity = <Date 2021-05-26.19:36:09.236>
    actor = 'brett.cannon'
    assignee = 'georg.brandl'
    closed = True
    closed_date = <Date 2009-03-31.18:56:48.551>
    closer = 'georg.brandl'
    components = ['Interpreter Core']
    creation = <Date 2008-01-01.16:39:25.550>
    creator = 'gvanrossum'
    dependencies = ['4704']
    files = ['9039', '11807', '12265', '12267', '12270', '12274', '12278', '12540', '12852', '12853', '12895']
    hgrepos = []
    issue_num = 1717
    keywords = ['patch']
    message_count = 92.0
    messages = ['59072', '63894', '64668', '70472', '70745', '70846', '72903', '72924', '72939', '74829', '74848', '74849', '74854', '74857', '77105', '77143', '77173', '77174', '77175', '77182', '77184', '77187', '77189', '77191', '77192', '77199', '77203', '77206', '77207', '77220', '77222', '77231', '77235', '77236', '77237', '77239', '77255', '77258', '77261', '77281', '77297', '77311', '77313', '77345', '77361', '77371', '77372', '77374', '77375', '77388', '77396', '77398', '77403', '77420', '77434', '77444', '78091', '78092', '78095', '78101', '78110', '78813', '78853', '78953', '80503', '80504', '80505', '80511', '80667', '80699', '80706', '80709', '80751', '80752', '80753', '80754', '80770', '80780', '80781', '80782', '80830', '80843', '80907', '81008', '81373', '82258', '82260', '82262', '84859', '195849', '394452', '394459']
    nosy_count = 13.0
    nosy_names = ['lemburg', 'brett.cannon', 'georg.brandl', 'rhettinger', 'amaury.forgeotdarc', 'mark.dickinson', 'atuining', 'pitrou', 'christian.heimes', 'benjamin.peterson', 'gpolo', 'python-dev', 'Nils Kattenbeck']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'patch review'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue1717'
    versions = ['Python 3.0', 'Python 3.1']

    @gvanrossum
    Copy link
    Member Author

    Should I apply this? There are more places that reference __cmp__ in
    the library. OTOH there are some folks who would like to see __cmp__
    make a come-back as a shorthand for defining 6 comparison operators, for
    totally-ordered types. (I'm still waiting for a PEP describing this
    though.) Even in that case I'm not sure that the code I'm proposing to
    delete here would be useful.

    @gvanrossum gvanrossum self-assigned this Jan 1, 2008
    @gvanrossum gvanrossum added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels Jan 1, 2008
    @gvanrossum
    Copy link
    Member Author

    __cmp__ is not coming back.

    @birkenfeld
    Copy link
    Member

    Bumping priority.

    @benjaminp
    Copy link
    Contributor

    Ping

    @gvanrossum
    Copy link
    Member Author

    Can someone other than me test and apply this? It seems still relevant,
    and __cmp__ is not coming back.

    @gvanrossum gvanrossum removed their assignment Aug 5, 2008
    @birkenfeld
    Copy link
    Member

    Additionally, there are still lots of references to __cmp__ in the
    library which should be ripped out.

    @birkenfeld
    Copy link
    Member

    Bumping priority even further. This shouldn't make it past rc.

    @benjaminp
    Copy link
    Contributor

    Guido's patch breaks these tests:

    test_descr test_hash test_long test_richcmp test_set

    @brettcannon
    Copy link
    Member

    Since we are making 3.0 issues deferred blockers dropping the priority.

    @mdickinson
    Copy link
    Member

    Guido's patch breaks these tests:

    test_descr test_hash test_long test_richcmp test_set

    It looks like all these are easily fixed: all these tests were making
    outdated assumptions and needed updating.

    Here's a patch that fixes these tests.

    One other detail:

    In test_descr.py, there are tests for 'overridden behavior for static
    classes' and 'overridden behavior for dynamic classes', using test classes
    'Proxy' and 'DProxy'; apart from the name change, the 'dynamic' code is
    identical to the 'static' code, so I removed it. I guess this had to do
    with the __dynamic__ class attribute, which is ancient history, no?

    @benjaminp
    Copy link
    Contributor

    Thanks, Mark! Applied in r66920.

    @birkenfeld
    Copy link
    Member

    The library still has __cmp__ functions defined here and there, e.g. in
    xmlrpc/client.py.

    @birkenfeld birkenfeld reopened this Oct 16, 2008
    @mdickinson
    Copy link
    Member

    Presumably any nonzero entries for tp_compare in type initializers
    should be looked at closely, as well?

    I see nonzero tp_compare entries in:
    Modules/_tkinter.c
    Modules/parsermodule.c
    Objects/cellobject.c
    Objects/descrobject.c
    PC/winreg.c
    Objects/setobject.c
    (but that last one just raises an error pointing out that cmp can't be
    used to compare sets, so maybe that's okay).

    @benjaminp
    Copy link
    Contributor

    Let's lower the priority on this.

    @mdickinson
    Copy link
    Member

    Stage 1 committed in r69025 (py3k) and r69026 (release30-maint).

    @mdickinson
    Copy link
    Member

    Can anyone who uses tkinter give me some advice? Does PyTclObject in
    _tkinter.c need to have its tp_richcompare method implemented? And if so,
    how do I go about testing the implementation? It seems that PyTclObjects
    aren't directly exposed to Python under 'import tkinter'.

    I'll hold off on any more checkins until the 3.0.1 thread on python-dev
    has resolved itself.

    @gpolo
    Copy link
    Mannequin

    gpolo mannequin commented Jan 28, 2009

    Mark,

    I'm not a very huge user of tkinter, but I can tell you it would be
    tricky to try getting a PyTclObject. It needs to be exposed if you want
    to test it without relying on Tcl, but, to me they are just a
    "temporary" object that serves to indicate the caller that it needs to
    be converted to something else since _tkinter itself wasn't able to do
    it. For this reason I would actually prefer to them not be comparable.

    @mdickinson
    Copy link
    Member

    Thanks, Guilherme.

    For this reason I would actually prefer to them not be comparable.

    That's fine with me, so long as we can be sure that there's no existing
    code that depends on them being comparable. I can't figure out whether
    there's any legitimate way that the tp_compare slot (which is currently
    implemented) of a PyTclObject could ever be called.

    @mdickinson
    Copy link
    Member

    I'm not going to get more time to work on this before
    the weekend, so if anyone else wants to take over please
    feel free.

    Still to do for stage 2: cell objects and slot
    wrapper objects need to have tp_richcompare
    implemented, to replace the tp_compare slots that
    are being removed.

    @rhettinger
    Copy link
    Contributor

    For 3.0, are you going to keep tp_compare slot in existence and just
    assert that it is NULL? Then in 3.1, remove the slot entirely?

    @mdickinson
    Copy link
    Member

    If I understand Christian's plan correctly, it was to:

    (1) raise TypeError for non-NULL tp_compare, and
    (2) rename tp_compare to tp_reserved (with type void *).

    and both of these would happen with 3.0.1, so no difference between
    3.0.1 and 3.1.0.

    It seems to me that if tp_compare is actually going to be removed then
    that should be done in 3.0.1; else third-party stuff that works with
    3.0.x will fail with 3.1, due to the various tp_* fields being out of sync.

    It would be nice not to have tp_reserved hanging around for the duration
    of 3.x. (Similarly for nb_reserved.)

    @rhettinger
    Copy link
    Contributor

    Instead of tp_reserved, the name should be tp_deprecated_compare.

    There should be a python-dev discussion around when to actually remove
    the slot:

    3.0.1 -- binary incompatibility between minor releases (BAD)
    3.1.0 -- uncomfortable for writers who have to add #ifdefs
    4.0.0 -- no pain, just wasted space
    3.1.5 -- just plain mean :-)

    @benjaminp
    Copy link
    Contributor

    Actually, I would like to repurpose tp_compare as tp_bytes for the
    __bytes__ method.

    @brettcannon
    Copy link
    Member

    On Thu, Jan 29, 2009 at 07:30, Benjamin Peterson <report@bugs.python.org> wrote:

    Benjamin Peterson <benjamin@python.org> added the comment:

    Actually, I would like to repurpose tp_compare as tp_bytes for the
    __bytes__ method.

    Repurposing would be extremely bad as that would mean it is possible
    for people to actually compile code with a busted __bytes__
    implementation.

    @benjaminp
    Copy link
    Contributor

    On Thu, Jan 29, 2009 at 2:39 PM, Brett Cannon <report@bugs.python.org> wrote:

    Brett Cannon <brett@python.org> added the comment:

    On Thu, Jan 29, 2009 at 07:30, Benjamin Peterson <report@bugs.python.org> wrote:
    >
    > Benjamin Peterson <benjamin@python.org> added the comment:
    >
    > Actually, I would like to repurpose tp_compare as tp_bytes for the
    > __bytes__ method.

    Repurposing would be extremely bad as that would mean it is possible
    for people to actually compile code with a busted __bytes__
    implementation.

    Wasn't there another case of an old slot being reused?

    @brettcannon
    Copy link
    Member

    > On Thu, Jan 29, 2009 at 07:30, Benjamin Peterson <report@bugs.python.org> wrote:
    >>
    >> Benjamin Peterson <benjamin@python.org> added the comment:
    >>
    >> Actually, I would like to repurpose tp_compare as tp_bytes for the
    >> __bytes__ method.
    >
    > Repurposing would be extremely bad as that would mean it is possible
    > for people to actually compile code with a busted __bytes__
    > implementation.

    Wasn't there another case of an old slot being reused?

    Not that I can remember, but I'm sure someone will correct me if I'm wrong.

    @mdickinson
    Copy link
    Member

    Here's stage 2: remove uses of tp_compare from Objects and Modules, and
    replace uses of PyObject_Compare with PyObject_RichCompareBool.
    PyObject_Compare, cmp and friends still haven't been removed at this
    stage.

    In detail:

    • for cell objects, method wrapper objects, PyTclObjects, and
      PyST_Objects (in the parser module), remove the defined tp_compare
      methods and implement tp_richcompare instead.
    • add tests for cell comparisons and PyST_Object comparisons;
      reenable
      tests for method wrapper comparisons. There are no tests for the
      PyTclObject comparisons.
    • remove tp_compare method from sets (all it did was emit an error
      message about the nonsensicality of doing order comparisons on sets)
    • in Objects/rangeobject.c and ElementTree, replace uses of
      PyObject_Compare with PyObject_RichCompareBool

    @pitrou
    Copy link
    Member

    pitrou commented Jan 31, 2009

    I haven't stared very closely but it looks ok.
    ("spanish armada" might be replaced with "spanish inquisition", though)

    @mdickinson
    Copy link
    Member

    Thanks for the review, Antoine.

    Stage 2 applied to py3k in r69181, merged to 3.0 in r69182.

    cmp, PyObject_Cmp and PyObject_Compare removed in r69184 (py3k) and r69185
    (release30-maint).

    There's still the rename of the tp_compare slot to deal with, and a fair
    amount of cleaning up and documentation fixing to do.

    @mdickinson
    Copy link
    Member

    All relevant changes from the py3k-issue1717 branch have now been merged into the py3k
    branch (and from there into the 3.0 maintenance branch), in a series of revisions.
    Here they are, listed in py3k/release30-maint pairs:

    r69188, r69189,
    r69190, r69191,
    r69192, r69193,
    r69214, r69215,
    r69218, r69221,
    r69224, r69225.

    The idea to raise TypeError on non-NULL tp_compare was abandoned after Martin pointed
    out that it would be a binary incompatible change _[1], but Nick Coghlan suggested a
    DeprecationWarning when tp_compare is non-NULL and tp_richcompare is NULL _[2], and
    remarked that the warning should also be implemented for Python 2.7 when run with the -
    3 option.

    Still to do before this can be closed:

    • fix up Doc/extending/newtypes.rst; I think Georg has said he'll
      take care of this, so once everything else is done I'll just reassign
      this issue to him and let him get on with it.

    • add Nick Coghlan's suggested DeprecationWarning.

    • grep through the sources looking for tp_compare, __cmp__, cmpfunc,
      PyObject_Cmp, PyObject_Compare and cmp, and check all remaining
      references are legitimate.

    • update pybench; there's a separate issue already open for this.
      (bpo-4704), and it looks like Antoine and Marc-André are on the
      case.

    • anything else that I've forgotten.

    Thanks everyone for your help so far, especially Christian for much of
    the original code and Antoine for code and review.

    [1] http://mail.python.org/pipermail/python-dev/2009-February/085797.html
    [2] http://mail.python.org/pipermail/python-dev/2009-February/085809.html

    @mdickinson
    Copy link
    Member

    Deprecation warning for types that implement tp_compare but not
    tp_richcompare added in r69431, r69432.

    Just the doc fixes in Doc/extending/newtypes.rst left. Assigning to Georg
    and reducing priority.

    @atuining
    Copy link
    Mannequin

    atuining mannequin commented Feb 16, 2009

    Removing cmp() breaks distutils. I get the following exception, for
    example using the just released version 3.0.1:

    Traceback (most recent call last):
      File "setup.py", line 318, in <module>
        classifiers = classifiers)
      File "c:\Python30\lib\distutils\core.py", line 149, in setup
        dist.run_commands()
      File "c:\Python30\lib\distutils\dist.py", line 942, in run_commands
        self.run_command(cmd)
      File "c:\Python30\lib\distutils\dist.py", line 962, in run_command
        cmd_obj.run()
      File "c:\Python30\lib\distutils\command\build.py", line 128, in run
        self.run_command(cmd_name)
      File "c:\Python30\lib\distutils\cmd.py", line 317, in run_command
        self.distribution.run_command(command)
      File "c:\Python30\lib\distutils\dist.py", line 962, in run_command
        cmd_obj.run()
      File "c:\Python30\lib\distutils\command\build_ext.py", line 306, in run
        force=self.force)
      File "c:\Python30\lib\distutils\ccompiler.py", line 1110, in new_compiler
        return klass(None, dry_run, force)
      File "c:\Python30\lib\distutils\cygwinccompiler.py", line 314, in __init__
        if self.gcc_version <= "2.91.57":
      File "c:\Python30\lib\distutils\version.py", line 64, in __le__
        c = self._cmp(other)
      File "c:\Python30\lib\distutils\version.py", line 341, in _cmp
        return cmp(self.version, other.version)
    NameError: global name 'cmp' is not defined

    @benjaminp
    Copy link
    Contributor

    Fixed in r69682.

    @mdickinson
    Copy link
    Member

    Darn. That's really very annoying. Apologies for missing this one.

    Thanks for the quick fix, Benjamin.

    @birkenfeld
    Copy link
    Member

    Documentation updated in r70863.

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Aug 22, 2013

    New changeset 64e004737837 by R David Murray in branch '3.3':
    bpo-18324: set_payload now correctly handles binary input.
    http://hg.python.org/cpython/rev/64e004737837

    @Septatrix
    Copy link
    Mannequin

    Septatrix mannequin commented May 26, 2021

    Has there been any resolution regarding sortTestMethodsUsing? See https://bugs.python.org/msg77261

    I spend a decent time and read the documentation thrice before realizing it received an old-style compare function. Brett's proposal for a new attribute seems like a sane way to do this without breaking backwards compatibility. Or will this continue using an old-style compare function for the foreseeable future?

    @brettcannon
    Copy link
    Member

    Has there been any resolution regarding sortTestMethodsUsing?

    My suspicion is if the docs don't suggest there's something else then nothing has been changed.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests