Skip to content

Commit af61e8c

Browse files
authored
Merge pull request #150 from bluescarni/pr/py312_fixes
Fixes for Python 3.12
2 parents 44c5d1a + 76d0e4a commit af61e8c

27 files changed

+2287
-1453
lines changed

doc/install.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ pygmo has the following **mandatory** runtime dependencies:
1717
Additionally, pygmo has the following **optional** runtime
1818
dependencies:
1919

20-
* `dill <https://dill.readthedocs.io>`__, which can be used as an
21-
alternative serialization backend,
2220
* `Matplotlib <https://matplotlib.org/>`__, which is used by a few
2321
plotting utilities,
2422
* `NetworkX <https://networkx.github.io/>`__, which is used for

pygmo/__init__.py

Lines changed: 87 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,38 @@
77
# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
88

99
from ._check_deps import *
10+
1011
# Version setup.
1112
from ._version import __version__
13+
1214
# We import the sub-modules into the root namespace
1315
from .core import *
1416
from .plotting import *
1517
from ._py_islands import *
1618
from ._py_problems import *
1719
from ._py_bfes import *
1820
from ._py_algorithms import *
21+
1922
# Patch the problem class.
2023
from . import _patch_problem
24+
2125
# Patch the algorithm class.
2226
from . import _patch_algorithm
27+
2328
# Patch the bfe class.
2429
from . import _patch_bfe
30+
2531
# Patch the island class.
2632
from . import _patch_island
33+
2734
# Patch the policies.
2835
from . import _patch_r_policy
2936
from . import _patch_s_policy
37+
3038
# Patch the topology.
3139
from . import _patch_topology
3240
import cloudpickle as _cloudpickle
41+
3342
# Explicitly import the test submodule
3443
from . import test
3544
import atexit as _atexit
@@ -69,7 +78,7 @@
6978
# of the syntax translate(udp, translation) for all udps
7079

7180

72-
def _translate_init(self, prob=None, translation=[0.]):
81+
def _translate_init(self, prob=None, translation=[0.0]):
7382
"""
7483
Args:
7584
prob: a user-defined problem (either Python or C++), or an instance of :class:`~pygmo.problem`
@@ -109,13 +118,20 @@ def _translate_init(self, prob=None, translation=[0.]):
109118
# of the syntax decompose(udp, ..., ) for all udps
110119

111120

112-
def _decompose_init(self, prob=None, weight=[0.5, 0.5], z=[0., 0.], method='weighted', adapt_ideal=False):
121+
def _decompose_init(
122+
self,
123+
prob=None,
124+
weight=[0.5, 0.5],
125+
z=[0.0, 0.0],
126+
method="weighted",
127+
adapt_ideal=False,
128+
):
113129
"""
114130
Args:
115131
prob: a user-defined problem (either Python or C++), or an instance of :class:`~pygmo.problem`
116132
(if *prob* is :data:`None`, a :class:`~pygmo.null_problem` will be used in its stead)
117-
weight (array-like object): the vector of weights :math:`\\boldsymbol \lambda`
118-
z (array-like object): the reference point :math:`\mathbf z^*`
133+
weight (array-like object): the vector of weights :math:`\\boldsymbol \\lambda`
134+
z (array-like object): the reference point :math:`\\mathbf z^*`
119135
method (str): a string containing the decomposition method chosen
120136
adapt_ideal (bool): when :data:`True`, the reference point is adapted at each fitness evaluation
121137
to be the ideal point
@@ -273,6 +289,7 @@ def _population_init(self, prob=None, size=0, b=None, seed=None):
273289
274290
"""
275291
from .core import _random_device_next
292+
276293
# Check input params.
277294
if not isinstance(size, int):
278295
raise TypeError("the 'size' parameter must be an integer")
@@ -296,8 +313,9 @@ def _population_init(self, prob=None, size=0, b=None, seed=None):
296313
__original_population_init(self, prob, size, seed)
297314
else:
298315
# A bfe was specified. Same as above with the problem.
299-
__original_population_init(self, prob, b if type(
300-
b) == bfe else bfe(b), size, seed)
316+
__original_population_init(
317+
self, prob, b if type(b) == bfe else bfe(b), size, seed
318+
)
301319

302320

303321
setattr(population, "__init__", _population_init)
@@ -334,56 +352,63 @@ def _island_init(self, **kwargs):
334352
return
335353

336354
# If we are not dealing with a def ctor, we always need the algo argument.
337-
if not 'algo' in kwargs:
355+
if not "algo" in kwargs:
338356
raise KeyError(
339357
"the mandatory 'algo' parameter is missing from the list of arguments "
340-
"of the island constructor")
341-
algo = kwargs.pop('algo')
358+
"of the island constructor"
359+
)
360+
algo = kwargs.pop("algo")
342361
algo = algo if type(algo) == algorithm else algorithm(algo)
343362

344363
# Population setup. We either need an input pop, or the prob and size,
345364
# plus optionally seed and b.
346-
if 'pop' in kwargs and ('prob' in kwargs or 'size' in kwargs or 'seed' in kwargs or 'b' in kwargs):
365+
if "pop" in kwargs and (
366+
"prob" in kwargs or "size" in kwargs or "seed" in kwargs or "b" in kwargs
367+
):
347368
raise KeyError(
348369
"if the 'pop' argument is provided, the 'prob', 'size', 'seed' and 'b' "
349-
"arguments must not be provided")
350-
elif 'pop' in kwargs:
351-
pop = kwargs.pop('pop')
352-
elif 'prob' in kwargs and 'size' in kwargs:
353-
pop = population(prob=kwargs.pop('prob'),
354-
size=kwargs.pop('size'), seed=kwargs.pop('seed') if 'seed' in kwargs else None,
355-
b=kwargs.pop('b') if 'b' in kwargs else None)
370+
"arguments must not be provided"
371+
)
372+
elif "pop" in kwargs:
373+
pop = kwargs.pop("pop")
374+
elif "prob" in kwargs and "size" in kwargs:
375+
pop = population(
376+
prob=kwargs.pop("prob"),
377+
size=kwargs.pop("size"),
378+
seed=kwargs.pop("seed") if "seed" in kwargs else None,
379+
b=kwargs.pop("b") if "b" in kwargs else None,
380+
)
356381
else:
357382
raise KeyError(
358383
"unable to construct a population from the arguments of "
359384
"the island constructor: you must either pass a population "
360385
"('pop') or a set of arguments that can be used to build one "
361-
"('prob', 'size' and, optionally, 'seed' and 'b')")
386+
"('prob', 'size' and, optionally, 'seed' and 'b')"
387+
)
362388

363389
# UDI, if any.
364-
if 'udi' in kwargs:
365-
args = [kwargs.pop('udi'), algo, pop]
390+
if "udi" in kwargs:
391+
args = [kwargs.pop("udi"), algo, pop]
366392
else:
367393
args = [algo, pop]
368394

369395
# Replace/selection policies, if any.
370-
if 'r_pol' in kwargs:
371-
r_pol = kwargs.pop('r_pol')
396+
if "r_pol" in kwargs:
397+
r_pol = kwargs.pop("r_pol")
372398
r_pol = r_pol if type(r_pol) == r_policy else r_policy(r_pol)
373399
args.append(r_pol)
374400
else:
375401
args.append(r_policy())
376402

377-
if 's_pol' in kwargs:
378-
s_pol = kwargs.pop('s_pol')
403+
if "s_pol" in kwargs:
404+
s_pol = kwargs.pop("s_pol")
379405
s_pol = s_pol if type(s_pol) == s_policy else s_policy(s_pol)
380406
args.append(s_pol)
381407
else:
382408
args.append(s_policy())
383409

384410
if len(kwargs) != 0:
385-
raise KeyError(
386-
'unrecognised keyword arguments: {}'.format(list(kwargs.keys())))
411+
raise KeyError("unrecognised keyword arguments: {}".format(list(kwargs.keys())))
387412

388413
__original_island_init(self, *args)
389414

@@ -417,6 +442,7 @@ def _mbh_init(self, algo=None, stop=5, perturb=1e-2, seed=None):
417442
418443
"""
419444
import numbers
445+
420446
if algo is None:
421447
# Use the compass search algo for default init.
422448
algo = compass_search()
@@ -538,40 +564,43 @@ def _archi_init(self, n=0, t=topology(), **kwargs):
538564
raise TypeError("the 'n' parameter must be an integer")
539565
if n < 0:
540566
raise ValueError(
541-
"the 'n' parameter must be non-negative, but it is {} instead".format(n))
567+
"the 'n' parameter must be non-negative, but it is {} instead".format(n)
568+
)
542569

543570
# Replace the 'pop_size' kw arg with just 'size', for later use in the
544571
# island ctor.
545572

546-
if 'size' in kwargs:
573+
if "size" in kwargs:
547574
raise KeyError(
548-
"the 'size' argument cannot appear among the named arguments of the archipelago constructor")
575+
"the 'size' argument cannot appear among the named arguments of the archipelago constructor"
576+
)
549577

550-
if 'pop_size' in kwargs:
578+
if "pop_size" in kwargs:
551579
# Extract 'pop_size', replace with just 'size'.
552-
ps_val = kwargs.pop('pop_size')
553-
kwargs['size'] = ps_val
580+
ps_val = kwargs.pop("pop_size")
581+
kwargs["size"] = ps_val
554582

555583
# Call the original init, which constructs an empty archi from a topology.
556584
t = t if type(t) == topology else topology(t)
557585
__original_archi_init(self, t)
558586

559-
if 'seed' in kwargs:
587+
if "seed" in kwargs:
560588
# Special handling of the 'seed' argument.
561589
from random import Random
562590
from .core import _max_unsigned
591+
563592
# Create a random engine with own state.
564593
RND = Random()
565594
# Get the seed from kwargs.
566-
seed = kwargs.pop('seed')
595+
seed = kwargs.pop("seed")
567596
if not isinstance(seed, int):
568597
raise TypeError("the 'seed' parameter must be an integer")
569598
# Seed the rng.
570599
RND.seed(seed)
571600
u_max = _max_unsigned()
572601
# Push back the islands with different seed.
573602
for _ in range(n):
574-
kwargs['seed'] = RND.randint(0, u_max)
603+
kwargs["seed"] = RND.randint(0, u_max)
575604
self.push_back(**kwargs)
576605

577606
else:
@@ -621,13 +650,22 @@ def _archi_push_back(self, *args, **kwargs):
621650
else:
622651
if len(args) != 1:
623652
raise ValueError(
624-
"{} positional arguments were provided, but this method accepts only a single positional argument".format(len(args)))
653+
"{} positional arguments were provided, but this method accepts only a single positional argument".format(
654+
len(args)
655+
)
656+
)
625657
if len(kwargs) != 0:
626658
raise ValueError(
627-
"if a positional argument is passed to this method, then no keyword arguments must be passed, but {} keyword arguments were passed instead".format(len(kwargs)))
659+
"if a positional argument is passed to this method, then no keyword arguments must be passed, but {} keyword arguments were passed instead".format(
660+
len(kwargs)
661+
)
662+
)
628663
if type(args[0]) != island:
629664
raise TypeError(
630-
"the positional argument passed to this method must be an island, but the type of the argument is '{}' instead".format(type(args[0])))
665+
"the positional argument passed to this method must be an island, but the type of the argument is '{}' instead".format(
666+
type(args[0])
667+
)
668+
)
631669
self._push_back(args[0])
632670

633671

@@ -708,8 +746,7 @@ def set_serialization_backend(name):
708746
The valid backends are:
709747
710748
* ``'pickle'`` (i.e., the standard Python :mod:`pickle` module),
711-
* ``'cloudpickle'``,
712-
* ``'dill'`` (from the `dill <https://pypi.org/project/dill/>`__ library).
749+
* ``'cloudpickle'``.
713750
714751
.. warning::
715752
@@ -722,29 +759,28 @@ def set_serialization_backend(name):
722759
723760
Raises:
724761
TypeError: if *name* is not a :class:`str`
725-
ValueError: if *name* is not one of ``['pickle', 'cloudpickle', 'dill']``
726-
ImportError: if *name* is ``'dill'`` but the dill module is not installed
762+
ValueError: if *name* is not one of ``['pickle', 'cloudpickle']``
727763
728764
"""
729765
if not isinstance(name, str):
730766
raise TypeError(
731-
"The serialization backend must be specified as a string, but an object of type {} was provided instead".format(type(name)))
767+
"The serialization backend must be specified as a string, but an object of type {} was provided instead".format(
768+
type(name)
769+
)
770+
)
732771
global _serialization_backend
733772
if name == "pickle":
734773
import pickle
774+
735775
_serialization_backend = pickle
736776
elif name == "cloudpickle":
737777
_serialization_backend = _cloudpickle
738-
elif name == "dill":
739-
try:
740-
import dill
741-
_serialization_backend = dill
742-
except ImportError:
743-
raise ImportError(
744-
"The 'dill' serialization backend was specified, but the dill module is not installed.")
745778
else:
746779
raise ValueError(
747-
"The serialization backend '{}' is not valid. The valid backends are: ['pickle', 'cloudpickle', 'dill']".format(name))
780+
"The serialization backend '{}' is not valid. The valid backends are: ['pickle', 'cloudpickle']".format(
781+
name
782+
)
783+
)
748784

749785

750786
def get_serialization_backend():

0 commit comments

Comments
 (0)