My poorly written tests suggests that the module works as intended. I fear this is to good to be true. I don't known how to write unit tests for this. I'm new to writing tests and I think this module would be hard for a unit test master to test.



# Constants.
SP = ' '
EMPTY = ''

def is_singleton(tag):
    return tag in SINGLETONS

def not_singleton(tag):
    return is_singleton(tag) == False

def html_attributes(**kw):
    # 'attrs' is the elements attributes.
    # Iterate over the keys and values of the kw dict
    # and transform them into a string of html 
    # attributes. Two html attribute keys are 
    # Python keywords 'class' and 'id' to set
    # the id and class of and element use:
    # cls for class and '_id' for 'id.'
    attrs = EMPTY
    n_attrs = len(kw)
    for key, value in zip(kw.keys(), kw.values()):
        if key == 'cls':
            key = 'class'

        if key == '_id':
            key = 'id'

        if n_attrs > 1:
            attrs += '{}="{}"{}'.format(key, value, SP)
           attrs += '{}="{}"'.format(key, value)
    return attrs.rstrip(SP)

def tagify(tagname, data=EMPTY, **kw):
    if isinstance(data, str):
        data = data.replace('\n', '<br>')
    attrs = html_attributes(**kw)

    if not attrs:
        opentag = '<{}>'.format(tagname)
        opentag = '<{}{}{}>'.format(tagname, SP, attrs)

    if not_singleton(tagname):
        closetag = '</{}>'.format(tagname)
        closetag = None

    if not closetag:
        return '{}'.format(opentag)

    if data:
        return '{}{}{}'.format(opentag, data, closetag)
        return '{}{}'.format(opentag, closetag)

def tag(tagname, **deco_kw):
    Decorate a functions output with html by
    passing it through tagify.
    def deco(func):
        def wraps(*args, **kw):
            content = func(*args, **kw)
            return tagify(tagname, content, **deco_kw)
        return wraps
    return deco

def tests():
    This is a temporary function for
    testing the module.
    Please dont include this in any reviews.
    @tag('li', cls='link', _id='list-item')
    def link(name, **kw):
        return tagify('a', name, **kw)

    @tag('article', cls='main', _id='spam')
    def paragraph(content, **kw):
        return tagify('p', content, **kw)

    print(link(__name__, src=__file__))
    print(paragraph(list(range(10)), _id='monty'))

if __name__ == '__main__':

test() output

<li id="list-item" class="link"><a src="/">__main__</a></li>
<article id="spam" class="main"><p id="monty">[0, 1, 2, 3, 4]</p></article>
  • 1
    \$\begingroup\$ Could you please tell us why you can't use any dependency? Or at least Python's builtins? \$\endgroup\$ – Grajdeanu Alex. Dec 27 '17 at 18:27
  • \$\begingroup\$ @MrGrj Its not that I couldn't use third party modules like lxml or builtins like html.dom. I wanted something simple and pretty. \$\endgroup\$ – Ricky Wilson Dec 27 '17 at 18:45

The better way to do this would be to use html_lib, but short of that, here are a few suggestions.

not_singleton is useless. Just use not singleton.

Use kw.items instead of zip(kw.keys(), kw.values()).

Don't use SP, use ' '.


Styleguide (PEP8)

  • avoid useless comments
  • you should have two new lines between your methods
  • docstrings should be written within triple double-quotes
  • after # you should have a space

Identity vs equality

There is a simple rule of thumb to tell you when to use == or is.

  • == is for value equality. Use it when you would like to know if two objects have the same value.
  • is is for reference equality. Use it when you would like to know if two references refer to the same object.

For example:

def not_singleton(tag):
    return is_singleton(tag) == False

Should actually be:

def not_singleton(tag):
    return is_singleton(tag) is False

Iterating over keys and values of a dict

Instead of this:

for key, value in zip(kw.keys(), kw.values()):

You should do this:

for key, value in kw.items():

To be continued

  • \$\begingroup\$ is_singleton(tag) is False: please, just do not is_singleton(tag) \$\endgroup\$ – Daniel Jan 11 '18 at 9:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.