Skip to content

Commit 5d74502

Browse files
frradpchtsp
andauthored
remove more of the mypy ignore list (#830)
* remove `mps_lp.py` from mypy ignore list * remove tests from mypy blacklist * python 3.9 compatible `Union` * logic simplification * fix gurobi env test * remove docs from blacklist * actually implement `is_single_use_license` * type ignores --------- Co-authored-by: Franco Peschiera <[email protected]>
1 parent a3f5655 commit 5d74502

File tree

8 files changed

+97
-76
lines changed

8 files changed

+97
-76
lines changed

doc/KPyCon2009/code/beerdistribution.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
x = pulp.LpVariable.dicts("route", (warehouses, bars), lowBound=0, cat=pulp.LpInteger)
4646

4747
# The objective function is added to 'prob' first
48-
prob += sum([x[w][b] * costs[w][b] for (w, b) in routes]), "Sum_of_Transporting_Costs"
48+
prob += sum([x[w][b] * costs[w][b] for (w, b) in routes]), "Sum_of_Transporting_Costs" # type: ignore[call-overload]
4949

5050
# Supply maximum constraints are added to prob for each supply node (warehouse)
5151
for w in warehouses:
@@ -75,4 +75,4 @@
7575
print(v.name, "=", v.varValue)
7676

7777
# The optimised objective function value is printed to the screen
78-
print("Total Cost of Transportation = ", prob.objective.value())
78+
print("Total Cost of Transportation = ", prob.objective.value()) # type: ignore[union-attr]

doc/source/_static/plotter.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python
22

3-
from matplotlib import rc
3+
from matplotlib import rc # type: ignore[import-not-found]
44

55
rc("text", usetex=True)
66
rc("font", family="serif")
@@ -28,12 +28,12 @@ def plot_interval(a, c, x_left, x_right, i, fbound):
2828
title(rf"Elasticized constraint\_{i} $C(x)= {c} $")
2929

3030

31-
figure()
32-
subplots_adjust(hspace=0.5)
31+
figure() # type: ignore[name-defined]
32+
subplots_adjust(hspace=0.5) # type: ignore[name-defined]
3333

3434
fbound = "proportionFreeBound"
3535
i = 1
36-
subplot(2, 1, i)
36+
subplot(2, 1, i) # type: ignore[name-defined]
3737
a = [0.01, 0.01]
3838
c = 200
3939
x_left = 0.97 * c
@@ -42,14 +42,14 @@ def plot_interval(a, c, x_left, x_right, i, fbound):
4242
plot_interval(a, c, x_left, x_right, i, fb_string)
4343

4444
i += 1
45-
subplot(2, 1, i)
45+
subplot(2, 1, i) # type: ignore[name-defined]
4646
a = [0.02, 0.05]
4747
c = 500
4848
x_left = 0.9 * c # scale of window
4949
x_right = 1.2 * c # scale of window
5050
fb_string = f"{fbound}List = [{a[0]},{a[1]}]"
5151
plot_interval(a, c, x_left, x_right, i, fb_string)
52-
savefig("freebound.jpg")
53-
savefig("freebound.pdf")
52+
savefig("freebound.jpg") # type: ignore[name-defined]
53+
savefig("freebound.pdf") # type: ignore[name-defined]
5454

5555
# vim: fenc=utf-8: ft=python:sw=4:et:nu:fdm=indent:fdn=1:syn=python

doc/source/conf.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# serve to show the default.
1212

1313
import sys, os
14+
from typing import Any
1415

1516
# If extensions (or modules to document with autodoc) are in another directory,
1617
# add these directories to sys.path here. If the directory is relative to the
@@ -79,12 +80,12 @@
7980

8081
# List of directories, relative to source directory, that shouldn't be searched
8182
# for source files.
82-
exclude_trees = []
83+
exclude_trees: list[None] = []
8384

8485
# List of patterns, relative to source directory, that match files and
8586
# directories to ignore when looking for source files.
8687
# This pattern also affects html_static_path and html_extra_path.
87-
exclude_patterns = []
88+
exclude_patterns: list[None] = []
8889

8990
# The reST default role (used for this markup: `text`) to use for all documents.
9091
# default_role = None
@@ -111,15 +112,15 @@
111112

112113
# The theme to use for HTML and HTML Help pages. Major themes that come with
113114
# Sphinx are currently 'default' and 'sphinxdoc'.
114-
import sphinx_rtd_theme
115+
import sphinx_rtd_theme # type: ignore[import-untyped]
115116

116117
html_theme = "sphinx_rtd_theme"
117118

118119
# Theme options are theme-specific and customize the look and feel of a theme
119120
# further. For a list of options available for each theme, see the
120121
# documentation.
121122
# html_theme_options = {}
122-
html_theme_options = {
123+
html_theme_options: dict[str, Any] = {
123124
# 'fixed_sidebar': True,
124125
# 'stickysidebar': True,
125126
# 'github_banner': True,

pulp/apis/gurobi_api.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,10 +163,9 @@ def __init__(
163163

164164
# set the output of gurobi
165165
if not self.msg:
166-
if self.manage_env:
167-
self.env_options["OutputFlag"] = 0
168-
else:
169-
self.env_options["OutputFlag"] = 0
166+
self.env_options["OutputFlag"] = 0
167+
168+
if not self.manage_env:
170169
self.solver_params["OutputFlag"] = 0
171170

172171
def __del__(self):

pulp/mps_lp.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,9 @@ def readMPS(path: str, sense: int, dropConsNames: bool = False) -> MPS:
158158

159159
with open(path) as reader:
160160
for line in reader:
161-
line = re.split(" |\t", line)
162-
line = [x.strip() for x in line]
163-
line = list(filter(None, line))
161+
line = re.split(" |\t", line) # type: ignore[assignment]
162+
line = [x.strip() for x in line] # type: ignore[assignment]
163+
line = list(filter(None, line)) # type: ignore[assignment]
164164

165165
if line[0] == "ENDATA":
166166
break
@@ -229,19 +229,19 @@ def readMPS(path: str, sense: int, dropConsNames: bool = False) -> MPS:
229229
raise const.PulpError(
230230
"Other RHS name was given even though name was set after RHS tag."
231231
)
232-
readMPSSetRhs(line, constraints)
232+
readMPSSetRhs(line, constraints) # type: ignore[arg-type]
233233
elif mode == CORE_FILE_RHS_MODE_NO_NAME:
234-
readMPSSetRhs(line, constraints)
234+
readMPSSetRhs(line, constraints) # type: ignore[arg-type]
235235
if line[0] not in rhs_names:
236236
rhs_names.append(line[0])
237237
elif mode == CORE_FILE_BOUNDS_MODE_NAME_GIVEN:
238238
if line[1] != bnd_names[-1]:
239239
raise const.PulpError(
240240
"Other BOUNDS name was given even though name was set after BOUNDS tag."
241241
)
242-
readMPSSetBounds(line, variable_info)
242+
readMPSSetBounds(line, variable_info) # type: ignore[arg-type]
243243
elif mode == CORE_FILE_BOUNDS_MODE_NO_NAME:
244-
readMPSSetBounds(line, variable_info)
244+
readMPSSetBounds(line, variable_info) # type: ignore[arg-type]
245245
if line[1] not in bnd_names:
246246
bnd_names.append(line[1])
247247
constraints_list = list(constraints.values())
@@ -312,19 +312,19 @@ def writeMPS(
312312
if mpsSense != lp.sense:
313313
n = cobj.name
314314
cobj = -cobj
315-
cobj.name = n
315+
cobj.name = n # type: ignore[union-attr]
316316
if rename:
317-
constrNames, varNames, cobj.name = lp.normalisedNames()
317+
constrNames, varNames, cobj.name = lp.normalisedNames() # type: ignore[union-attr]
318318
# No need to call self.variables() again, we have just filled self._variables:
319-
vs = lp._variables # type: ignore
319+
vs = lp._variables
320320
else:
321321
vs = lp.variables()
322322
varNames = {v.name: v.name for v in vs}
323323
constrNames = {c: c for c in lp.constraints}
324324
model_name = lp.name
325325
if rename:
326326
model_name = "MODEL"
327-
objName = cobj.name
327+
objName = cobj.name # type: ignore[union-attr]
328328
if not objName:
329329
objName = "OBJ"
330330

@@ -346,7 +346,7 @@ def writeMPS(
346346
for v in vs:
347347
name = varNames[v.name]
348348
columns_lines.extend(
349-
writeMPSColumnLines(coefs[name], v, mip, name, cobj, objName)
349+
writeMPSColumnLines(coefs[name], v, mip, name, cobj, objName) # type: ignore[arg-type]
350350
)
351351

352352
# right hand side
@@ -382,7 +382,7 @@ def writeMPS(
382382
if not rename:
383383
return vs
384384
else:
385-
return vs, varNames, constrNames, cobj.name
385+
return vs, varNames, constrNames, cobj.name # type: ignore[union-attr]
386386

387387

388388
def writeMPSColumnLines(

pulp/tests/test_gurobipy_env.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from pulp import GUROBI, LpProblem, LpVariable, const
44

55
try:
6-
import gurobipy as gp
6+
import gurobipy as gp # type: ignore[import-not-found]
77
from gurobipy import GRB
88
except ImportError:
99
gp = None
@@ -14,6 +14,19 @@ def check_dummy_env():
1414
pass
1515

1616

17+
def is_single_use_license() -> bool:
18+
try:
19+
with gp.Env() as env1:
20+
with gp.Env() as env2:
21+
pass
22+
except gp.GurobiError as ge:
23+
if ge.errno == gp.GRB.Error.NO_LICENSE:
24+
print("single use license")
25+
print(f"Error code {ge.errno}: {ge}")
26+
return True
27+
return False
28+
29+
1730
def generate_lp() -> LpProblem:
1831
prob = LpProblem("test", const.LpMaximize)
1932
x = LpVariable("x", 0, 1)
@@ -40,7 +53,10 @@ def test_gp_env(self):
4053
solver.close()
4154
check_dummy_env()
4255

43-
@unittest.SkipTest
56+
@unittest.skipUnless(
57+
is_single_use_license(),
58+
"this test is only expected to pass with a single-use license",
59+
)
4460
def test_gp_env_no_close(self):
4561
# Not closing results in an error for a single use license.
4662
with gp.Env(params=self.env_options) as env:
@@ -64,7 +80,10 @@ def test_multiple_gp_env(self):
6480

6581
check_dummy_env()
6682

67-
@unittest.SkipTest
83+
@unittest.skipUnless(
84+
is_single_use_license(),
85+
"this test is only expected to pass with a single-use license",
86+
)
6887
def test_backward_compatibility(self):
6988
"""
7089
Backward compatibility check as previously the environment was not being
@@ -101,7 +120,10 @@ def test_multiple_solves(self):
101120
solver2.close()
102121
check_dummy_env()
103122

104-
@unittest.SkipTest
123+
@unittest.skipUnless(
124+
is_single_use_license(),
125+
"this test is only expected to pass with a single-use license",
126+
)
105127
def test_leak(self):
106128
"""
107129
Check that we cannot initialise environments after a memory leak. On a

0 commit comments

Comments
 (0)