Permalink
Browse files

pyzfs: python3 support (library 1/2)

These changes are efficient and valid in python 2 and 3. For the
most part, they are also pythonic.

* 2to3 conversion
* add __future__ imports
* iterator changes
* integer division
* relative import fixes

Reviewed-by: John Ramsden <johnramsden@riseup.net>
Reviewed-by: Neal Gompa <ngompa@datto.com>
Reviewed-by: loli10K <ezomori.nozomu@gmail.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Antonio Russo <antonio.e.russo@gmail.com>
Closes #8096
  • Loading branch information...
aerusso authored and madwizard committed Aug 22, 2018
1 parent 84a2c4b commit 53c213a33304291dd8fb995348cec1dadef06bcb
@@ -38,6 +38,7 @@
Maximum length of any ZFS name.
'''
from __future__ import absolute_import, division, print_function

from ._constants import (
MAXNAMELEN,
@@ -18,10 +18,12 @@
Important `libzfs_core` constants.
"""

from __future__ import absolute_import, division, print_function


# https://stackoverflow.com/a/1695250
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
enums = dict(((b, a) for a, b in enumerate(sequential)), **named)
return type('Enum', (), enums)


@@ -26,6 +26,7 @@
The parameters and exceptions are documented in the `libzfs_core` interfaces.
"""
from __future__ import absolute_import, division, print_function

import errno
import re
@@ -102,8 +103,9 @@ def lzc_snapshot_translate_errors(ret, errlist, snaps, props):

def _map(ret, name):
if ret == errno.EXDEV:
pool_names = map(_pool_name, snaps)
same_pool = all(x == pool_names[0] for x in pool_names)
pool_names = iter(map(_pool_name, snaps))
pool_name = next(pool_names, None)
same_pool = all(x == pool_name for x in pool_names)
if same_pool:
return lzc_exc.DuplicateSnapshots(name)
else:
@@ -270,7 +272,8 @@ def _map(ret, name):
def lzc_release_translate_errors(ret, errlist, holds):
if ret == 0:
return
for _, hold_list in holds.iteritems():
for snap in holds:
hold_list = holds[snap]
if not isinstance(hold_list, list):
raise lzc_exc.TypeError('holds must be in a list')

@@ -705,15 +708,17 @@ def _handle_err_list(ret, errlist, names, exception, mapper):

if len(errlist) == 0:
suppressed_count = 0
names = list(zip(names, range(2)))
if len(names) == 1:
name = names[0]
name, _ = names[0]
else:
name = None
errors = [mapper(ret, name)]
else:
errors = []
suppressed_count = errlist.pop('N_MORE_ERRORS', 0)
for name, err in errlist.iteritems():
for name in errlist:
err = errlist[name]
errors.append(mapper(err, name))

raise exception(errors, suppressed_count)
@@ -26,6 +26,7 @@
are directly returned. Error conditions are signalled by exceptions
rather than by integer error codes.
"""
from __future__ import absolute_import, division, print_function

import errno
import functools
@@ -485,8 +486,8 @@ def lzc_hold(holds, fd=None):
errors.lzc_hold_translate_errors(ret, errlist, holds, fd)
# If there is no error (no exception raised by _handleErrList), but errlist
# is not empty, then it contains missing snapshots.
assert all(x == errno.ENOENT for x in errlist.itervalues())
return errlist.keys()
assert all(errlist[x] == errno.ENOENT for x in errlist)
return list(errlist.keys())


def lzc_release(holds):
@@ -521,7 +522,8 @@ def lzc_release(holds):
'''
errlist = {}
holds_dict = {}
for snap, hold_list in holds.iteritems():
for snap in holds:
hold_list = holds[snap]
if not isinstance(hold_list, list):
raise TypeError('holds must be in a list')
holds_dict[snap] = {hold: None for hold in hold_list}
@@ -531,8 +533,8 @@ def lzc_release(holds):
errors.lzc_release_translate_errors(ret, errlist, holds)
# If there is no error (no exception raised by _handleErrList), but errlist
# is not empty, then it contains missing snapshots and tags.
assert all(x == errno.ENOENT for x in errlist.itervalues())
return errlist.keys()
assert all(errlist[x] == errno.ENOENT for x in errlist)
return list(errlist.keys())


def lzc_get_holds(snapname):
@@ -1873,9 +1875,9 @@ def lzc_get_props(name):
mountpoint_val = '/' + name
else:
mountpoint_val = None
result = {k: v['value'] for k, v in result.iteritems()}
result = {k: result[k]['value'] for k in result}
if 'clones' in result:
result['clones'] = result['clones'].keys()
result['clones'] = list(result['clones'].keys())
if mountpoint_val is not None:
result['mountpoint'] = mountpoint_val
return result
@@ -47,6 +47,7 @@
- a value can be a list of dictionaries that adhere to this format
- all elements of a list value must be of the same type
"""
from __future__ import absolute_import, division, print_function

import numbers
from collections import namedtuple
@@ -19,6 +19,7 @@
`libzfs_core` uses. The modules expose CFFI objects required
to make calls to functions in the libraries.
"""
from __future__ import absolute_import, division, print_function

import threading
import importlib
@@ -47,7 +48,7 @@ def __getattr__(self, name):
ffi = FFI()

for module_name in MODULES:
module = importlib.import_module("." + module_name, __package__)
module = importlib.import_module("." + module_name, __name__)
ffi.cdef(module.CDEF)
lib = LazyLibrary(ffi, module.LIBRARY)
setattr(module, "ffi", ffi)
@@ -17,6 +17,7 @@
"""
Python bindings for ``libnvpair``.
"""
from __future__ import absolute_import, division, print_function

CDEF = """
typedef ... nvlist_t;
@@ -17,6 +17,7 @@
"""
Python bindings for ``libzfs_core``.
"""
from __future__ import absolute_import, division, print_function

CDEF = """
@@ -17,6 +17,7 @@
"""
Utility functions for casting to a specific C type.
"""
from __future__ import absolute_import, division, print_function

from .bindings.libnvpair import ffi as _ffi

@@ -17,6 +17,7 @@
"""
Exceptions that can be raised by libzfs_core operations.
"""
from __future__ import absolute_import, division, print_function

import errno
from ._constants import (
Oops, something went wrong.

0 comments on commit 53c213a

Please sign in to comment.