Skip to content

Commit f10e721

Browse files
committed
Raise TypeError for bad arguments to Mv
If `Mv` is passed the wrong number of positional arguments, it used to either silently ignore them, or crash with an unclear message. This would either confuse users, or mask bugs. With this change, it becomes a `TypeError` to pass either too many or too few parameters.
1 parent a29f146 commit f10e721

File tree

2 files changed

+51
-31
lines changed

2 files changed

+51
-31
lines changed

galgebra/mv.py

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -173,13 +173,18 @@ def characterise_Mv(self):
173173
# helper methods called by __init__. Note that these names must not change,
174174
# as the part of the name after `_make_` is public API via the string
175175
# argument passed to __init__.
176+
#
177+
# The double underscores in argument names are to force the passing
178+
# positionally. When python 3.8 is the lowest supported version, we can
179+
# switch to using the / syntax from PEP570
176180

177181
@staticmethod
178-
def _make_grade(ga, *args, **kwargs):
182+
def _make_grade(ga, __name_or_coeffs, __grade, **kwargs):
179183
""" Make a pure grade multivector. """
180-
grade = args[1]
181-
if utils.isstr(args[0]):
182-
root = args[0] + '__'
184+
grade = __grade
185+
if utils.isstr(__name_or_coeffs):
186+
name = __name_or_coeffs
187+
root = name + '__'
183188
if isinstance(kwargs['f'], bool) and not kwargs['f']: #Is a constant mulitvector function
184189
return sum([Symbol(root + super_script, real=True) * base
185190
for (super_script, base) in zip(ga.blade_super_scripts[grade], ga.blades[grade])])
@@ -191,69 +196,72 @@ def _make_grade(ga, *args, **kwargs):
191196
else: #Is a multivector function of tuple kwargs['f'] variables
192197
return sum([Function(root + super_script, real=True)(*kwargs['f']) * base
193198
for (super_script, base) in zip(ga.blade_super_scripts[grade], ga.blades[grade])])
194-
elif isinstance(args[0],(list,tuple)):
195-
if len(args[0]) <= len(ga.blades[grade]):
199+
elif isinstance(__name_or_coeffs, (list, tuple)):
200+
coeffs = __name_or_coeffs
201+
if len(coeffs) <= len(ga.blades[grade]):
196202
return sum([coef * base
197-
for (coef, base) in zip(args[0], ga.blades[grade][:len(args[0])])])
203+
for (coef, base) in zip(coeffs, ga.blades[grade][:len(coeffs)])])
198204
else:
199205
raise ValueError("Too many coefficients")
200206
else:
201207
raise TypeError("Expected a string, list, or tuple")
202208

203209
@staticmethod
204-
def _make_scalar(ga, *args, **kwargs):
210+
def _make_scalar(ga, __name_or_value, **kwargs):
205211
""" Make a scalar multivector """
206-
if utils.isstr(args[0]):
212+
if utils.isstr(__name_or_value):
213+
name = __name_or_value
207214
if 'f' in kwargs and isinstance(kwargs['f'],bool):
208215
if kwargs['f']:
209-
return Function(args[0])(*ga.coords)
216+
return Function(name)(*ga.coords)
210217
else:
211-
return Symbol(args[0], real=True)
218+
return Symbol(name, real=True)
212219
else:
213220
if 'f' in kwargs and isinstance(kwargs['f'],tuple):
214-
return Function(args[0])(*kwargs['f'])
221+
return Function(name)(*kwargs['f'])
215222
else:
216-
return args[0]
223+
value = __name_or_value
224+
return value
217225

218226
@staticmethod
219-
def _make_vector(ga, *args, **kwargs):
227+
def _make_vector(ga, __name_or_coeffs, **kwargs):
220228
""" Make a vector multivector """
221-
return Mv._make_grade(ga, args[0], 1, **kwargs)
229+
return Mv._make_grade(ga, __name_or_coeffs, 1, **kwargs)
222230

223231
@staticmethod
224-
def _make_bivector(ga, *args, **kwargs):
232+
def _make_bivector(ga, __name_or_coeffs, **kwargs):
225233
""" Make a bivector multivector """
226-
return Mv._make_grade(ga, args[0], 2, **kwargs)
234+
return Mv._make_grade(ga, __name_or_coeffs, 2, **kwargs)
227235

228236
@staticmethod
229-
def _make_pseudo(ga, *args, **kwargs):
237+
def _make_pseudo(ga, __name_or_coeffs, **kwargs):
230238
""" Make a pseudo scalar multivector """
231-
return Mv._make_grade(ga, args[0], ga.n, **kwargs)
239+
return Mv._make_grade(ga, __name_or_coeffs, ga.n, **kwargs)
232240

233241
@staticmethod
234-
def _make_mv(ga, *args, **kwargs):
242+
def _make_mv(ga, __name, **kwargs):
235243
""" Make a general (2**n components) multivector """
236-
tmp = Mv._make_scalar(ga, args[0], **kwargs)
244+
tmp = Mv._make_scalar(ga, __name, **kwargs)
237245
for grade in ga.n_range:
238-
tmp += Mv._make_grade(ga, args[0], grade + 1, **kwargs)
246+
tmp += Mv._make_grade(ga, __name, grade + 1, **kwargs)
239247
return tmp
240248

241249
@staticmethod
242-
def _make_spinor(ga, *args, **kwargs):
250+
def _make_spinor(ga, __name, **kwargs):
243251
""" Make a general even (spinor) multivector """
244-
tmp = Mv._make_scalar(ga, args[0], **kwargs)
252+
tmp = Mv._make_scalar(ga, __name, **kwargs)
245253
for grade in ga.n_range:
246254
if (grade + 1) % 2 == 0:
247-
tmp += Mv._make_grade(ga, args[0], grade + 1, **kwargs)
255+
tmp += Mv._make_grade(ga, __name, grade + 1, **kwargs)
248256
return tmp
249257

250258
@staticmethod
251-
def _make_odd(ga, *args, **kwargs):
259+
def _make_odd(ga, __name_or_coeffs, **kwargs):
252260
""" Make a general odd multivector """
253261
tmp = S(0)
254262
for grade in ga.n_range:
255263
if (grade + 1) % 2 == 1:
256-
tmp += Mv._make_grade(args[0], grade + 1, **kwargs)
264+
tmp += Mv._make_grade(__name_or_coeffs, grade + 1, **kwargs)
257265
return tmp
258266

259267
# aliases
@@ -297,15 +305,18 @@ def __init__(self, *args, **kwargs):
297305
self.characterise_Mv()
298306
else:
299307
if utils.isstr(args[1]):
300-
args = list(args)
301-
mode = args.pop(1)
308+
make_args = list(args)
309+
mode = make_args.pop(1)
302310
make_func = getattr(Mv, '_make_{}'.format(mode), None)
303311
if make_func is None:
304312
raise ValueError('{!r} is not an allowed multivector type.'.format(mode))
305-
self.obj = make_func(self.Ga, *args, **kwargs)
313+
self.obj = make_func(self.Ga, *make_args, **kwargs)
306314
elif isinstance(args[1], int): # args[1] = r (integer) Construct grade r multivector
307315
if args[1] == 0:
308-
self.obj = Mv._make_scalar(self.Ga, *args, **kwargs)
316+
# make_grade does not work for scalars (gh-82)
317+
make_args = list(args)
318+
make_args.pop(1)
319+
self.obj = Mv._make_scalar(self.Ga, *make_args, **kwargs)
309320
else:
310321
self.obj = Mv._make_grade(self.Ga, *args, **kwargs)
311322
else:

test/test_mv.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,12 @@ def test_rep_switching(self):
8484
self.assertFalse(m0_base.is_blade_rep) # original should not change
8585
self.assertTrue(m0_base_blade.is_blade_rep)
8686
self.assertEqual(m0, m0_base_blade)
87+
88+
def test_construction(self):
89+
(ga, e_1, e_2, e_3) = Ga.build('e*1|2|3')
90+
91+
# illegal arguments
92+
with self.assertRaises(TypeError):
93+
ga.mv('A', 'vector', "too many arguments")
94+
with self.assertRaises(TypeError):
95+
ga.mv('A', 'grade') # too few arguments

0 commit comments

Comments
 (0)