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

bpo-42403: Use @staticmethod in importlib #23395

Merged
merged 1 commit into from
Nov 20, 2020
Merged

bpo-42403: Use @staticmethod in importlib #23395

merged 1 commit into from
Nov 20, 2020

Conversation

vstinner
Copy link
Member

@vstinner vstinner commented Nov 19, 2020

Use @staticmethod on methods using @classmethod but don't use their
cls parameter, of the following classes:

  • BuiltinImporter
  • FrozenImporter
  • WindowsRegistryFinder
  • PathFinder

https://bugs.python.org/issue42403

@tiran
Copy link
Member

tiran commented Nov 19, 2020

What's the point? Are there any benefits in using staticmethod? I personally consider staticmethod a misfeature that should be avoided.

@vstinner
Copy link
Member Author

What's the point? Are there any benefits in using staticmethod? I personally consider staticmethod a misfeature that should be avoided.

See https://julien.danjou.info/guide-python-static-class-abstract-methods/

I like @staticmethod to show that the method is not a method but a function put into the namespace of a class, to show that it does not use the class state (but can use external variables, like modules and the module global variables).

@vstinner
Copy link
Member Author

Hum, test_importlib fails with this change. Example:

======================================================================

ERROR: test_for_top_level (test.test_importlib.test_metadata_api.APITests)

----------------------------------------------------------------------

Traceback (most recent call last):

  File "/home/travis/build/python/cpython/Lib/test/test_importlib/test_metadata_api.py", line 38, in test_for_top_level

    distribution('egginfo-pkg').read_text('top_level.txt').strip(),

AttributeError: 'NoneType' object has no attribute 'strip'

@vstinner
Copy link
Member Author

Hum, test_importlib fails with this change.

It was a stupid mistake in my PR. It's now fixed ;-)

@JulienPalard
Copy link
Member

I agree that using staticmethod+hardcoding the class name is a bad idea, but it's not the case here: semantically those are staticmethods, not classmethods as they don't need to know in which class they are. Marking them as so is an information to the reader.

@vstinner
Copy link
Member Author

To be clear, this change doesn't prevent subclasses to access self or cls (if using @classmethod) in overriden methods.

@vstinner
Copy link
Member Author

Marking them as so is an information to the reader.

Yeah, that's the main purpose of this change.

Use @staticmethod on methods using @classmethod but don't use their
cls parameter, of the following classes:

* BuiltinImporter
* FrozenImporter
* WindowsRegistryFinder
* PathFinder
@vstinner
Copy link
Member Author

PR rebased after I merged my other importlib PR #23397.

@vstinner
Copy link
Member Author

@tiran: So are you ok with this change?

@tiran
Copy link
Member

tiran commented Nov 20, 2020

@tiran: So are you ok with this change?

I don't have a hard opinion here. If you like to change it, go ahead.

I personally don't like staticmethod because I don't see a valid use case for it. I see them as sign of bad design. Either a method is bound to an instance, bound to a class, or it should be a function in the first place.

@vstinner
Copy link
Member Author

I personally don't like staticmethod because I don't see a valid use case for it. I see them as sign of bad design. Either a method is bound to an instance, bound to a class, or it should be a function in the first place.

The importer API requires create_module(sep) to be a method, to be able to call my_impoter.create_module(sep). See importlib.abc.Loader ABC. The implementation is free to use a static method (no extra parameter), a class method (cls) or a regular method (self).

  • ExtensionFileLoader.create_module() uses self
  • BuiltinImporter.create_module() doesn't use self nor self
  • LazyLoader.create_module() uses self

I'm a little bit confused between "loader" and "importer", but it doesn't matter much to explain my point ;-)

Marking a method with @staticmethod or @classmethod doesn't prevent to override the method in a subclass with any kind of method (static method, class method or regular method). Calling parent super().create_module(spef) method also works in all cases.

@vstinner vstinner merged commit 3be8e22 into python:master Nov 20, 2020
@vstinner vstinner deleted the importlib_staticmethod branch November 20, 2020 13:44
adorilson pushed a commit to adorilson/cpython that referenced this pull request Mar 13, 2021
Use @staticmethod on methods using @classmethod but don't use their
cls parameter on the following classes:

* BuiltinImporter
* FrozenImporter
* WindowsRegistryFinder
* PathFinder

Leave methods using @_requires_builtin or @_requires_frozen unchanged,
since this decorator requires the wrapped method to have an extra parameter
(cls or self).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants