From 2b22398cff1d270091a5f615cfb4461f446e094a Mon Sep 17 00:00:00 2001 From: Pablo Estrada Date: Fri, 25 Sep 2020 11:42:38 -0700 Subject: [PATCH 1/8] Adding linter tests on Appveyor configuration --- appveyor.yml | 1 + tools/install_appveyor_mingw.py | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 6d592052..a25d5eec 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,6 +5,7 @@ environment: secure: M+qvYgRh05fEw6G9aglK4g== matrix: + - BUILD_TYPE: "Pylint37-x64" - BUILD_TYPE: "Release" - BUILD_TYPE: "Debug" # At the moment the build fails upon module import diff --git a/tools/install_appveyor_mingw.py b/tools/install_appveyor_mingw.py index 777fbde7..1d2467ab 100755 --- a/tools/install_appveyor_mingw.py +++ b/tools/install_appveyor_mingw.py @@ -49,6 +49,7 @@ def run_command(raw_command, directory=None, verbose=True): print("Release build detected, tag is '" + os.environ['APPVEYOR_REPO_TAG_NAME'] + "'") is_python_build = 'Python' in BUILD_TYPE +is_python_lint = 'Pylint' in BUILD_TYPE # Check here for a list of installed software in the appveyor VMs: https://www.appveyor.com/docs/windows-images-software/ # USING: mingw64 8.1.0 @@ -64,8 +65,8 @@ def run_command(raw_command, directory=None, verbose=True): run_command(r'7z x -aoa -oC:\\ boost.7z', verbose=False) # Setup of the Python build variables (version based) -if is_python_build: - if 'Python37-x64' in BUILD_TYPE: +if is_python_build or is_python_lint: + if 'Python37-x64' in BUILD_TYPE or 'Pylint37-x64' in BUILD_TYPE: python_version = r'37' python_folder = r'Python37-x64' python_library = r'C:\\' + python_folder + r'\\python37.dll ' @@ -84,6 +85,12 @@ def run_command(raw_command, directory=None, verbose=True): pinterp = r"C:\\" + python_folder + r'\\python.exe' pip = r"C:\\" + python_folder + r'\\scripts\\pip' twine = r"C:\\" + python_folder + r'\\scripts\\twine' + # Set linter paths + pylint = r"C:\\" + python_folder + r'\\scripts\\pylint' + pycodestyle = r"C:\\" + python_folder + r'\\scripts\\pycodestyle' + mypy = r"C:\\" + python_folder + r'\\scripts\\mypy' + + module_install_path = r"C:\\" + python_folder + r'\\Lib\\site-packages\\pykep' # Install pip and deps. run_command(pinterp + r' --version', verbose=True) @@ -103,7 +110,7 @@ def run_command(raw_command, directory=None, verbose=True): r'-DBoost_DATE_TIME_LIBRARY_RELEASE=c:\\local\\lib\\libboost_date_time-mgw81-mt-x64-1_70.dll ' # Configuration step. -if is_python_build: +if is_python_build or is_python_lint: os.makedirs('build_keplerian_toolbox') os.chdir('build_keplerian_toolbox') run_command(r'cmake -G "MinGW Makefiles" .. ' + common_cmake_opts + \ @@ -149,7 +156,7 @@ def run_command(raw_command, directory=None, verbose=True): # Testing, packaging. -if is_python_build: +if is_python_build or is_python_lint: # Run the Python tests. run_command( pinterp + r' -c "from pykep import test; test.run_test_suite();"') @@ -173,3 +180,9 @@ def run_command(raw_command, directory=None, verbose=True): run_command(twine + r' upload -u darioizzo dist\\' + os.listdir('dist')[0]) + if is_python_lint: + # Run Python lint checks + run_command(pip + ' install pylint') + # Running pylint and erroring only on actual errors. Excluding + run_command(pylint + ' pykep -E') + From 3d9035be8069d5ca1f37f7b8f2595b9cb6776633 Mon Sep 17 00:00:00 2001 From: Pablo Estrada Date: Tue, 29 Sep 2020 14:34:59 -0700 Subject: [PATCH 2/8] allow C extensions to be loaded by pylint This cleans up the erroneous lint errors related to C-extensions. --- tools/install_appveyor_mingw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/install_appveyor_mingw.py b/tools/install_appveyor_mingw.py index 1d2467ab..a6a380da 100755 --- a/tools/install_appveyor_mingw.py +++ b/tools/install_appveyor_mingw.py @@ -184,5 +184,5 @@ def run_command(raw_command, directory=None, verbose=True): # Run Python lint checks run_command(pip + ' install pylint') # Running pylint and erroring only on actual errors. Excluding - run_command(pylint + ' pykep -E') + run_command(pylint + ' pykep -E --unsafe-load-any-extension=y') From 00310be0775484587b96c414123540f745f51203 Mon Sep 17 00:00:00 2001 From: Pablo Estrada Date: Tue, 29 Sep 2020 16:28:15 -0700 Subject: [PATCH 3/8] Including all dependencies in INSTALL_REQUIRES. Adding txt files to wheels. --- tools/wheel_setup.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/wheel_setup.py b/tools/wheel_setup.py index ea2c6edf..bf13aeb9 100644 --- a/tools/wheel_setup.py +++ b/tools/wheel_setup.py @@ -11,7 +11,7 @@ AUTHOR = 'Dario Izzo' AUTHOR_EMAIL = 'dario.izzo@gmail.com' LICENSE = 'GPLv3+/LGPL3+' -INSTALL_REQUIRES = ['numpy', 'scipy', 'matplotlib'] +INSTALL_REQUIRES = ['numpy', 'scipy', 'matplotlib', 'pygmo', 'sklearn', 'numba'] CLASSIFIERS = [ # How mature is this project? Common values are # 3 - Alpha @@ -43,8 +43,10 @@ def has_ext_modules(foo): return True -# Setup the list of external dlls. +# Setup the list of external dlls and other data files. import os.path + +PYKEP_UTIL_FILES = ['gravity_models/*/*txt'] if os.name == 'nt': mingw_wheel_libs = 'mingw_wheel_libs_python{}{}.txt'.format( sys.version_info[0], sys.version_info[1]) @@ -54,14 +56,14 @@ def has_ext_modules(foo): 'pykep.core': ['core.pyd'] + DLL_LIST, 'pykep.planet': ['planet.pyd'], 'pykep.sims_flanagan': ['sims_flanagan.pyd'], - 'pykep.util': ['util.pyd'] + 'pykep.util': ['util.pyd'] + PYKEP_UTIL_FILES } else: PACKAGE_DATA = { 'pykep.core': ['core.so'], 'pykep.planet': ['planet.so'], 'pykep.sims_flanagan': ['sims_flanagan.so'], - 'pykep.util': ['util.so'] + 'pykep.util': ['util.so'] + PYKEP_UTIL_FILES } setup(name=NAME, From f4804c831afaa32b9a3610e339db8b6cd7e7ddae Mon Sep 17 00:00:00 2001 From: Alberto Date: Wed, 30 Sep 2020 16:33:06 -0500 Subject: [PATCH 4/8] Fix errors spotted by pylint --- pykep/orbit_plots/_plots.py | 16 ++++++++++++---- pykep/phasing/_dbscan.py | 19 ++++++++++--------- pykep/phasing/_lambert.py | 2 +- pykep/trajopt/_direct.py | 20 ++++++++++++++++++++ pykep/trajopt/_indirect.py | 15 +++++++++++++++ 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/pykep/orbit_plots/_plots.py b/pykep/orbit_plots/_plots.py index bf70ff9b..78aaa213 100644 --- a/pykep/orbit_plots/_plots.py +++ b/pykep/orbit_plots/_plots.py @@ -290,13 +290,17 @@ def plot_taylor(r0, v0, m0, thrust, tof, mu, veff, N=60, units=1, color='b', leg x = [0.0] * N y = [0.0] * N z = [0.0] * N - + + # Replace r0, v0, m0 for r, v, m + r = r0 + v = v0 + m = m0 # We calculate the spacecraft position at each dt for i in range(N): x[i] = r[0] / units y[i] = r[1] / units z[i] = r[2] / units - r, v, m = propagate_taylor(r0, v0, m0, u, dt, mu, veff, -10, -10) + r, v, m = propagate_taylor(r, v, m, thrust, dt, mu, veff, -10, -10) # And we plot if legend: @@ -351,13 +355,17 @@ def plot_taylor_disturbance(r0, v0, m0, thrust, disturbance, tof, mu, veff, N=60 y = [0.0] * N z = [0.0] * N + # Replace r0, v0 and m0 + r = r0 + v = v0 + m = m0 # We calculate the spacecraft position at each dt for i in range(N): x[i] = r[0] / units y[i] = r[1] / units z[i] = r[2] / units - r0, v0, m0 = propagate_taylor_disturbance( - r0, v0, m0, thrust, disturbance, dt, mu, veff, -10, -10) + r, v, m = propagate_taylor_disturbance( + r, v, m, thrust, disturbance, dt, mu, veff, -10, -10) # And we plot if legend: diff --git a/pykep/phasing/_dbscan.py b/pykep/phasing/_dbscan.py index f328992c..fa2e4e2f 100644 --- a/pykep/phasing/_dbscan.py +++ b/pykep/phasing/_dbscan.py @@ -1,6 +1,6 @@ class dbscan(): """ - This class can be used to locate areas of the interplanetsry space that are 'dense' at one epoch. + This class can be used to locate areas of the interplanetary space that are 'dense' at one epoch. Essentially, it locates planet clusters """ from pykep.core import AU, EARTH_VELOCITY @@ -28,6 +28,7 @@ def __init__(self, planet_list): self.n_clusters = None self.members = None self.core_members = None + self._scaling = None def _orbital_metric(self, r, v): from pykep.core import DAY2SEC @@ -56,20 +57,20 @@ def cluster(self, t, eps=0.125, min_samples=10, metric='orbital', T=180, ref_r=A if metric == 'euclidean': self._X = [ [elem for tupl in p.eph(self._epoch) for elem in tupl] for p in self._asteroids] - scaling_vector = [ref_r] * 3 - scaling_vector += [ref_v] * 3 + self._scaling = [ref_r] * 3 + self._scaling += [ref_v] * 3 elif metric == 'euclidean_r': self._X = [list(p.eph(self._epoch)[0]) for p in self._asteroids] - scaling_vector = [ref_r] * 3 + self._scaling = [ref_r] * 3 elif metric == 'orbital': self._T = T self._X = [self._orbital_metric( *p.eph(self._epoch)) for p in self._asteroids] - scaling_vector = [1.] * 6 # no scaling + self._scaling = [1.] * 6 # no scaling self._X = numpy.array(self._X) - scaling_vector = numpy.array(scaling_vector) - self._X = self._X / scaling_vector[None, :] + self._scaling = numpy.array(self._scaling) + self._X = self._X / self._scaling[None, :] self._db = DBSCAN(eps=eps, min_samples=min_samples).fit(self._X) self._core_samples = self._db.core_sample_indices_ @@ -88,7 +89,7 @@ def cluster(self, t, eps=0.125, min_samples=10, metric='orbital', T=180, ref_r=A self.core_members[int(label)] = [ index for index in self._core_samples if self.labels[index] == label] - self._X = self._X * scaling_vector[None, :] + self._X = self._X * self._scaling[None, :] def pretty(self): """Prints the cluster lists.""" @@ -149,7 +150,7 @@ def plot_cluster_evolution(self, cluster_id=None, only_core=False, epochs=range( return if cluster_id >= self.n_clusters or cluster_id < 0: print( - "cluster_id should be larger then 0 and smaller than the number of clusters (-1)") + "cluster_id should be larger than 0 and smaller than the number of clusters (-1)") return if len(epochs) != 9: print("The epochs requested must be exactly 9 as to assemble 3x3 subplots") diff --git a/pykep/phasing/_lambert.py b/pykep/phasing/_lambert.py index 44bce757..336fd5ba 100644 --- a/pykep/phasing/_lambert.py +++ b/pykep/phasing/_lambert.py @@ -1,5 +1,5 @@ from pygmo.problem._base import base -from pygmo.util import hypervolume +from pygmo import hypervolume from pykep.planet import gtoc7 from pykep.orbit_plots import plot_planet, plot_lambert from pykep.core import lambert_problem, DAY2SEC, epoch, AU, damon diff --git a/pykep/trajopt/_direct.py b/pykep/trajopt/_direct.py index ddaf1f37..db46cde6 100644 --- a/pykep/trajopt/_direct.py +++ b/pykep/trajopt/_direct.py @@ -24,6 +24,26 @@ def __init__(self, mass=1000., thrust=0.3, isp=3000., nseg=10, mu=pk.MU_SUN, hf= self.leg.set_mu(mu) self.leg.high_fidelity = hf + def fitness(self): + """This function will be redefined in the inheriting classes + """ + pass + + def _plot_traj(self): + """This function will be redefined in the inheriting classes + """ + pass + + def _get_controls(self): + """This function will be redefined in the inheriting classes + """ + pass + + def _pretty(self): + """This function will be redefined in the inheriting classes + """ + pass + def get_nobj(self): return 1 diff --git a/pykep/trajopt/_indirect.py b/pykep/trajopt/_indirect.py index 1c965877..27737905 100644 --- a/pykep/trajopt/_indirect.py +++ b/pykep/trajopt/_indirect.py @@ -34,6 +34,21 @@ def __init__( raise TypeError( "Both atol and rtol must be an instance of either float or int.") + def fitness(self): + """This function will be redefined in the inheriting classes + """ + pass + + def _plot_traj(self): + """This function will be redefined in the inheriting classes + """ + pass + + def _pretty(self): + """This function will be redefined in the inheriting classes + """ + pass + def get_nobj(self): return 1 From 23c60b44ff3b4667911a591029adc55a915f0b2f Mon Sep 17 00:00:00 2001 From: albertoibm Date: Wed, 30 Sep 2020 17:46:00 -0500 Subject: [PATCH 5/8] define functions with full set of arguments in base class --- pykep/trajopt/_direct.py | 7 ++++--- pykep/trajopt/_indirect.py | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pykep/trajopt/_direct.py b/pykep/trajopt/_direct.py index db46cde6..c18aac78 100644 --- a/pykep/trajopt/_direct.py +++ b/pykep/trajopt/_direct.py @@ -29,17 +29,18 @@ def fitness(self): """ pass - def _plot_traj(self): + def _plot_traj(self, z, axis, units): """This function will be redefined in the inheriting classes """ pass - def _get_controls(self): + @staticmethod + def _get_controls(z): """This function will be redefined in the inheriting classes """ pass - def _pretty(self): + def _pretty(self, z): """This function will be redefined in the inheriting classes """ pass diff --git a/pykep/trajopt/_indirect.py b/pykep/trajopt/_indirect.py index 27737905..c6a22f65 100644 --- a/pykep/trajopt/_indirect.py +++ b/pykep/trajopt/_indirect.py @@ -34,17 +34,17 @@ def __init__( raise TypeError( "Both atol and rtol must be an instance of either float or int.") - def fitness(self): + def fitness(self, z): """This function will be redefined in the inheriting classes """ pass - def _plot_traj(self): + def _plot_traj(self, z, axes, units): """This function will be redefined in the inheriting classes """ pass - def _pretty(self): + def _pretty(self, z): """This function will be redefined in the inheriting classes """ pass From b6335c1a07ea39d722b17943254e464676556ba7 Mon Sep 17 00:00:00 2001 From: Pablo Estrada Date: Wed, 30 Sep 2020 15:52:50 -0700 Subject: [PATCH 6/8] Adding pygmo_plugins_nonfree dependency asd --- tools/wheel_setup.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/wheel_setup.py b/tools/wheel_setup.py index bf13aeb9..ca95bd64 100644 --- a/tools/wheel_setup.py +++ b/tools/wheel_setup.py @@ -11,7 +11,15 @@ AUTHOR = 'Dario Izzo' AUTHOR_EMAIL = 'dario.izzo@gmail.com' LICENSE = 'GPLv3+/LGPL3+' -INSTALL_REQUIRES = ['numpy', 'scipy', 'matplotlib', 'pygmo', 'sklearn', 'numba'] +INSTALL_REQUIRES = [ + 'numba', + 'numpy', + 'matplotlib', + 'pygmo', + 'pygmo_plugins_nonfree', + 'scipy', + 'sklearn', +] CLASSIFIERS = [ # How mature is this project? Common values are # 3 - Alpha From 8f66834a887928ec43080415022bb3c9a6e3d63d Mon Sep 17 00:00:00 2001 From: albertoibm Date: Wed, 30 Sep 2020 19:25:59 -0500 Subject: [PATCH 7/8] missed correction from previous commit --- pykep/trajopt/_direct.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pykep/trajopt/_direct.py b/pykep/trajopt/_direct.py index c18aac78..d18829e1 100644 --- a/pykep/trajopt/_direct.py +++ b/pykep/trajopt/_direct.py @@ -24,7 +24,7 @@ def __init__(self, mass=1000., thrust=0.3, isp=3000., nseg=10, mu=pk.MU_SUN, hf= self.leg.set_mu(mu) self.leg.high_fidelity = hf - def fitness(self): + def fitness(self, z): """This function will be redefined in the inheriting classes """ pass From d66c7523468fb464fdc4da6680bbb903be6047bc Mon Sep 17 00:00:00 2001 From: albertoibm Date: Fri, 2 Oct 2020 14:57:09 -0500 Subject: [PATCH 8/8] Disable lint check on two lines due to other known issues --- pykep/examples/_ex_utilities.py | 3 ++- pykep/phasing/_lambert.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pykep/examples/_ex_utilities.py b/pykep/examples/_ex_utilities.py index b6cab888..44e25bf9 100644 --- a/pykep/examples/_ex_utilities.py +++ b/pykep/examples/_ex_utilities.py @@ -52,7 +52,8 @@ def algo_factory(name, original_screen_output=True): pl = 5 else: pl = 0 - uda = pg.ipopt() + # Disable lint check on next line. Known issue (pagmo2/issues/261) + uda = pg.ipopt() # pylint: disable=no-member uda.set_integer_option("print_level", pl) uda.set_integer_option("acceptable_iter", 4) uda.set_integer_option("max_iter", 150) diff --git a/pykep/phasing/_lambert.py b/pykep/phasing/_lambert.py index 336fd5ba..0ccffa84 100644 --- a/pykep/phasing/_lambert.py +++ b/pykep/phasing/_lambert.py @@ -1,4 +1,4 @@ -from pygmo.problem._base import base +from pygmo.problem._base import base # pylint: disable=import-error from pygmo import hypervolume from pykep.planet import gtoc7 from pykep.orbit_plots import plot_planet, plot_lambert