Split the metaclass == type and from future boilerplate code.

The metaclass boilerplate is safe to apply en masse.  The future import
boilerplate needs code to be inspected to be sure that there aren't any
py2isms that need to be fixed.  Split these two checks so that we can
fix them independently

Be explicit about which files are grandfathered so we can fix them up one by one
This commit is contained in:
Toshio Kuratomi 2019-07-02 09:36:37 -07:00
parent 909f7f2ce5
commit 146a7f8ff6
8 changed files with 2110 additions and 73 deletions

View file

@ -1,3 +1,5 @@
:orphan:
Sanity Tests » boilerplate
==========================
@ -7,4 +9,3 @@ Most Python files should include the following boilerplate:
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

View file

@ -0,0 +1,51 @@
Sanity Tests » from __future__ boilerplate
==========================================
Most Python files should include the following boilerplate at the top of the file, right after the
comment header:
.. code-block:: python
from __future__ import (absolute_import, division, print_function)
This uses Python 3 semantics for absolute vs relative imports, division, and print. By doing this,
we can write code which is portable between Python 2 and Python 3 by following the Python 3 semantics.
absolute_import
---------------
When Python 2 encounters an import of a name in a file like ``import copy`` it attempts to load
``copy.py`` from the same directory as the file is in. This can cause problems if there is a python
file of that name in the directory and also a python module in ``sys.path`` with that same name. In
that case, Python 2 would load the one in the same directory and there would be no way to load the
one on ``sys.path``. Python 3 fixes this by making imports absolute by default. ``import copy``
will find ``copy.py`` from ``sys.path``. If you want to import ``copy.py`` from the same directory,
the code needs to be changed to perform a relative import: ``from . import copy``.
.. seealso::
* `Absolute and relative imports <https://www.python.org/dev/peps/pep-0328>`_
division
--------
In Python 2, the division operator (``/``) returns integer values when used with integers. If there
was a remainder, this part would be left off (aka, `floor division`). In Python 3, the division
operator (``/``) always returns a floating point number. Code that needs to calculate the integer
portion of the quotient needs to switch to using the floor division operator (`//`) instead.
.. seealso::
* `Changing the division operator <https://www.python.org/dev/peps/pep-0238>`_
print_function
--------------
In Python 2, :func:`python:print` is a keyword. In Python 3, :func:`python3:print` is a function with different
parameters. Using this ``__future__`` allows using the Python 3 print semantics everywhere.
.. seealso::
* `Make print a function <https://www.python.org/dev/peps/pep-3105>`_

View file

@ -0,0 +1,23 @@
Sanity Tests » __metaclass__ = type boilerplate
===============================================
Most Python files should include the following boilerplate at the top of the file, right after the
comment header and ``from __future__ import``:
.. code-block:: python
__metaclass__ = type
Python 2 has "new-style classes" and "old-style classes" whereas Python 3 only has new-style classes.
Adding the ``__metaclass__ = type`` boilerplate makes every class defined in that file into
a new-style class as well.
.. code-block:: python
from __future__ import absolute_import, division, print_function
__metaclass__ = type
class Foo:
# This is a new-style class even on Python 2 because of the __metaclass__
pass

View file

@ -1,72 +0,0 @@
#!/usr/bin/env python
import sys
def main():
skip = set([
'lib/ansible/compat/selectors/_selectors2.py',
'lib/ansible/module_utils/six/_six.py',
'setup.py',
])
prune = [
'contrib/inventory/',
'contrib/vault/',
'docs/',
'examples/',
'hacking/',
'lib/ansible/module_utils/',
'lib/ansible/modules/cloud/amazon/',
'lib/ansible/modules/cloud/cloudstack/',
'lib/ansible/modules/cloud/ovirt/',
'lib/ansible/modules/network/aos/',
'lib/ansible/modules/network/avi/',
'lib/ansible/modules/network/cloudengine/',
'lib/ansible/modules/network/eos/',
'lib/ansible/modules/network/ios/',
'lib/ansible/modules/network/netvisor/',
'lib/ansible/modules/network/nxos/',
'lib/ansible/modules/network/panos/',
'lib/ansible/modules/network/vyos/',
'lib/ansible/modules/windows/',
'lib/ansible/plugins/doc_fragments/',
'test/'
]
for path in sys.argv[1:] or sys.stdin.read().splitlines():
if path in skip:
continue
if any(path.startswith(p) for p in prune):
continue
with open(path, 'rb') as path_fd:
future_ok = None
metaclass_ok = None
lines = path_fd.read().splitlines()
if not lines:
continue
for line, text in enumerate(lines):
if text in (b'from __future__ import (absolute_import, division, print_function)',
b'from __future__ import absolute_import, division, print_function'):
future_ok = line
if text == b'__metaclass__ = type':
metaclass_ok = line
if future_ok and metaclass_ok:
break
if future_ok is None:
print('%s: missing: from __future__ import (absolute_import, division, print_function)' % path)
if metaclass_ok is None:
print('%s: missing: __metaclass__ = type' % path)
if __name__ == '__main__':
main()

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,6 @@
{
"extensions": [
".py"
],
"output": "path-message"
}

File diff suppressed because it is too large Load diff