HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Functions with mutable and non-mutable named tuples

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
nonwithtuplesnamedandfunctionsmutable

Problem

I am making some functions within a function for learning which when passed information about a named tuple: it returns a reference to a class object from which we can construct instances of the specified named tuple. Is there any way to make the code a bit cleaner? Any help would be great. The function pnamedtuple has other functions defined in it.

Here is my current functioning code:

```
import re, traceback, keyword
from goody import type_as_str

def pnamedtuple(type_name, field_names, mutable=False):
'''Passed information about a named tuple: it returns a reference to a class
object from which we can construct instances of the specified named tuple.'''

def show_listing(s):
for i, l in enumerate(s.split('\n'), 1):
print('{num: >3} {text}'.format(num=i, text=l.rstrip()))

def unique_list(l):
ulist = []
for thing in l:
if thing not in ulist:
ulist.append(thing)
return ulist

regex = re.compile('^([a-zA-Z]{1}\w*)$')
resplit = re.compile('[ ,]')
if re.match(regex, str(type_name)) == None:
raise SyntaxError('Illegal type name: ' + str(type_name))
if type(field_names) not in (list, str):
raise SyntaxError('Field names cannot be extracted: improper typing.' + str(field_names) + 'are not a list or a str, but instead: ' + type_as_str(field_names))
if type(field_names) is str:
fields = re.split(resplit, field_names)
fields = [f for f in fields if f not in (None, '')]
if type(field_names) is list:
fields = field_names
fields = unique_list(fields)
for field in fields:
if field in keyword.kwlist:
raise SyntaxError('Field name: (' + str(field) + ') is a keyword and cannot be used.')
if field[0].lower() not in 'abcdefghijklmnopqrstuvwxyz':
raise SyntaxError('Field name: (' + str(field) + ') doesn\'t start with a letter')

def init(field_names, mutable):
'''has al

Solution

Argh, code generation in Python. Well, in this case it seems safe as
you're not dealing with user code except for the variable names.

So a few suggestions then:

  • I'd typically expect that field_names as a list instead of a string


literal; it would matter if you were to use pnamedtuple from other
functions, because then you'd have to construct the string from a list
(probably) in many cases.

  • The dance with commas and string concatenation in prepr can be


written more cleanly with join as you already did in init.

  • And if you're on that, why not use format all the time as well.



  • get_fieldname strikes me as very ugly. I'd really prefer just the


keys themselves with the @property annotation.

  • I think that specifying multiple fields with the same name should be


an error instead of you having to deal with unique_list.

Feature requests (I probably won't use it, but these seem like obvious
additions to me):

  • Default values for fields. They would need to be literal values, or


you'd have to specify them as strings I guess, but having e.g. 0 as
default value for a vector tuple would be nice.

  • Deal with redefinition. This is a tricky one as you'd have to think


about what happens with old instances (or you just throw an error
instead).

  • Generate some documentation for the new class. At least the class


itself could use a hint like "This class was automagically generated
by pnamedtuple (at somefile.py:1234)."


All in all a nice application of metaprogramming, although I'm still not
a huge fan (cue the meme) of a string-based approach.

Context

StackExchange Code Review Q#79752, answer score: 2

Revisions (0)

No revisions yet.