Skip to content

Remove @builtinclass #2294

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

Merged
merged 4 commits into from
Oct 22, 2016
Merged

Remove @builtinclass #2294

merged 4 commits into from
Oct 22, 2016

Conversation

elazarg
Copy link
Contributor

@elazarg elazarg commented Oct 20, 2016

Following #599

@ddfisher
Copy link
Collaborator

Maybe @JukkaL can chime in here, but it seems to me that inheriting from object isn't the same as being a builtin class?

@elazarg
Copy link
Contributor Author

elazarg commented Oct 20, 2016

@ddfisher you mean "being object isn't the same as being a builtin class"? I agree. It can be replaced with a lookup in a set. But there should be a test demonstrating this need.

@ddfisher
Copy link
Collaborator

Ah, yep -- I misread that. It looks to me like we don't currently use the @builtinclass functionality anywhere at all, so we should either make it work or just kill it completely.

@elazarg
Copy link
Contributor Author

elazarg commented Oct 20, 2016

I guess either can be done in a separate PR.

@gvanrossum
Copy link
Member

The nearest_builtin_ancestor() is actually used in a check for instance layout conflicts. This is currently a no-op because only object is considered builtin, but it is meant to guard against e.g. M.I. from list and dict simultaneously. So please at least put a TODO in that function explaining that it should be expanded, not deleted.

The class in the test inherits from function to avoid warnings about compatibility of __add__
import typing
class A(int, str): pass # E: Instance layout conflict in multiple inheritance
class A(int, function): pass # E: Instance layout conflict in multiple inheritance
Copy link
Contributor Author

@elazarg elazarg Oct 21, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

str and int have conflicting definition of __add__, and this test is not about that.

@elazarg
Copy link
Contributor Author

elazarg commented Oct 21, 2016

Added check for "builtin.lower-case" since it covers many cases. Are there exceptions to this rule?

Turns out there were tests for this feature, but they were skipped.

@gvanrossum
Copy link
Member

That's a bizarre solution. Please roll that back so that it behaves exactly as before and file a separate bug. The issue is way more complicated than that -- every extension module may define "builtin" types (according to this definition).

@elazarg
Copy link
Contributor Author

elazarg commented Oct 22, 2016

I will roll back, but I don't understand the problem. Can you elaborate - what's the ultimate intended behavior?

  1. Before this PR, any module could declare @builtinclass type.
  2. In the previous version of this PR, only object is considered a builltin, so we don't warn about conflicting hierarchy.
  3. In the current solution, extension modules can "declare" builtin types, but they have to add them to the builtin module explicitly, and give them a lowercase name.

What's wrong with option 3 ?

@gvanrossum
Copy link
Member

Option 3 is not at all how Python actually works. Adding stuff to the builtins module is not what extension modules should do, and the all-lowercase naming convention only works reliably for a few well-known types like int, str, list.

When there is a layout conflict due to attempting to M.I. from two different extension classes, Python will reject the class definition at runtime, so mypy won't be finding new problems even if it did faithfully emulate the runtime behavior. But the runtime behavior is also impossible to emulate (it requires more information that can be expressed using PEP 484 and the @builtinclass decorator), and I propose not to bother, since it never worked anyway.

We should get rid of the builtinclass decorator from typeshed (there are no uses currently) and of the code in mypy related to is_builtinclass (what the previous version of this PR attempted). We can also get rid of nearest_builtin_ancestor() since the check that uses it does not add extra safety -- M.I. from two builtin classes typcally fails because of conflicting methods anyways. The two tests that expect that error message have code that is rejected for other reasons with the real typeshed -- try my -c 'class A(int, str): pass and see the errors fly by.

So mypy should just not bother trying to detect layout conflicts. The code block in check_multiple_inheritance() labeled # Verify that base class layouts are compatible. can just be deleted, as can the INSTANCE_LAYOUT_CONFLICT message.

Hope this helps!

@elazarg
Copy link
Contributor Author

elazarg commented Oct 22, 2016

It sure helps. Thank you!

@elazarg
Copy link
Contributor Author

elazarg commented Oct 22, 2016

Should I remove the tests altogether then?

@codecov-io
Copy link

codecov-io commented Oct 22, 2016

Current coverage is 83.09% (diff: 100%)

No coverage report found for master at 48fa2ef.

Powered by Codecov. Last update 48fa2ef...b2eaef5

@gvanrossum gvanrossum merged commit 2e19181 into python:master Oct 22, 2016
@gvanrossum
Copy link
Member

gvanrossum commented Oct 25, 2016 via email

@elazarg
Copy link
Contributor Author

elazarg commented Oct 25, 2016

The skipped tests. Which I removed in the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants