Python keyword.iskeyword() Examples

The following are 30 code examples of keyword.iskeyword(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module keyword , or try the search function .
Example #1
Source File: import_statement.py    From Jandroid with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def alias(self, value):
    if keyword.iskeyword(value):
      raise ValueError('%s is a reserved keyword.' % value)

    if value:
       # pylint: disable=access-member-before-definition
      if len(self.children) < 3:
        # If we currently have no alias, add one.
         # pylint: disable=access-member-before-definition
        self.children.append(
            snippet.TokenSnippet.Create(token.NAME, 'as', (0, 1)))
         # pylint: disable=access-member-before-definition
        self.children.append(
            snippet.TokenSnippet.Create(token.NAME, value, (0, 1)))
      else:
        # We already have an alias. Just update the value.
        # pylint: disable=access-member-before-definition
        self.children[2].value = value
    else:
      # Removing the alias. Strip the "as foo".
      self.children = [self.children[0]] # pylint: disable=line-too-long, attribute-defined-outside-init 
Example #2
Source File: keyword.py    From python-esppy with Apache License 2.0 6 votes vote down vote up
def dekeywordify(name):
    '''
    Add an underscore to names that are keywords

    Parameters
    ----------
    name : string
        The string to check against keywords

    Returns
    -------
    string
        Name changed to avoid keywords

    '''
    if keyword.iskeyword(name):
        return name + '_'
    return name 
Example #3
Source File: test_assign.py    From pyta with GNU General Public License v3.0 6 votes vote down vote up
def test_assign_complex_homogeneous(variables_dict):
    """test whether visitors properly set the type constraint of the a assign node representing a multi-target-assign
     with a homogeneous list as the value.
    """
    for variable_name in variables_dict:
        assume(not iskeyword(variable_name))
    program = ("x = ["
               + ", ".join([repr(value) for value in variables_dict.values()])
               + "]\n"
               + ", ".join(variables_dict.keys())
               + " = x")
    module, typeinferrer = cs._parse_text(program)
    ass_node = list(module.nodes_of_class(astroid.Assign))[0]
    for variable_name in variables_dict:
        var_tvar = module.type_environment.lookup_in_env(variable_name)
        assert typeinferrer.type_constraints.resolve(var_tvar).getValue() == ass_node.value.elts[0].inf_type.getValue() 
Example #4
Source File: namedlist.py    From appcompatprocessor with Apache License 2.0 6 votes vote down vote up
def _check_common(self, name, type_of_name):
        # tests that are common to both field names and the type name
        if len(name) == 0:
            raise ValueError('{0} names cannot be zero '
                             'length: {1!r}'.format(type_of_name, name))
        if _PY2:
            if not all(c.isalnum() or c=='_' for c in name):
                raise ValueError('{0} names can only contain '
                                 'alphanumeric characters and underscores: '
                                 '{1!r}'.format(type_of_name, name))
            if name[0].isdigit():
                raise ValueError('{0} names cannot start with a '
                                 'number: {1!r}'.format(type_of_name, name))
        else:
            if not name.isidentifier():
                raise ValueError('{0} names names must be valid '
                                 'identifiers: {1!r}'.format(type_of_name, name))
        if _iskeyword(name):
            raise ValueError('{0} names cannot be a keyword: '
                             '{1!r}'.format(type_of_name, name)) 
Example #5
Source File: related.py    From bioforum with MIT License 6 votes vote down vote up
def _check_related_name_is_valid(self):
        import keyword
        related_name = self.remote_field.related_name
        if related_name is None:
            return []
        is_valid_id = True
        if keyword.iskeyword(related_name):
            is_valid_id = False
        if not related_name.isidentifier():
            is_valid_id = False
        if not (is_valid_id or related_name.endswith('+')):
            return [
                checks.Error(
                    "The name '%s' is invalid related_name for field %s.%s" %
                    (self.remote_field.related_name, self.model._meta.object_name,
                     self.name),
                    hint="Related name must be a valid Python identifier or end with a '+'",
                    obj=self,
                    id='fields.E306',
                )
            ]
        return [] 
Example #6
Source File: gensuitemodule.py    From Computable with MIT License 6 votes vote down vote up
def identify(str):
    """Turn any string into an identifier:
    - replace space by _
    - replace other illegal chars by _xx_ (hex code)
    - append _ if the result is a python keyword
    """
    if not str:
        return "empty_ae_name_"
    rv = ''
    ok = string.ascii_letters + '_'
    ok2 = ok + string.digits
    for c in str:
        if c in ok:
            rv = rv + c
        elif c == ' ':
            rv = rv + '_'
        else:
            rv = rv + '_%02.2x_'%ord(c)
        ok = ok2
    if keyword.iskeyword(rv):
        rv = rv + '_'
    return rv

# Call the main program 
Example #7
Source File: bitstructs.py    From pymtl3 with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def mk_bitstruct( cls_name, fields, *, namespace=None, add_init=True,
                   add_str=True, add_repr=True, add_hash=True ):

  # copy namespace since  will mutate it
  namespace = {} if namespace is None else namespace.copy()

  # We assume fields is a dictionary and thus there won't be duplicate
  # field names. So we only check if the field names are indeed strings
  # and that they are not keywords.
  annos = {}
  for name, f in fields.items():
    if not isinstance( name, str ) or not name.isidentifier():
      raise TypeError( f'Field name {name!r} is not a valid identifier!' )
    if keyword.iskeyword( name ):
      raise TypeError( f'Field name {name!r} is a keyword!' )
    annos[ name ] = f

  namespace['__annotations__'] = annos
  cls = types.new_class( cls_name, (), {}, lambda ns: ns.update( namespace ) )
  return bitstruct( cls, add_init=add_init, add_str=add_str,
                    add_repr=add_repr, add_hash=add_hash ) 
Example #8
Source File: arya.py    From arya with Apache License 2.0 6 votes vote down vote up
def buildattributestring(self, attr):
        """
        Builds the attribute string for the object creation

        attr is a dict containing name value pairs of the attribute and value
        """
        if not isinstance(attr, dict):
            attr = dict()

        parmlist = []
        for k, v in attr.items():
            if k not in self.EXCLUDEATTR:
                # any properly formed xml/json should have keywords already
                # escaped however this is just a sanity check. also, it
                # misses 'to' which is not a keyword in python, but is
                # treated as such in pymeta oh well
                if keyword.iskeyword(k):
                    k += '_'

                v = repr(v)
                parmlist.append('%s=%s' % (k, v))

        attribstr = ', '.join(parmlist)

        return attribstr 
Example #9
Source File: compat.py    From aiohttp_apiset with Apache License 2.0 6 votes vote down vote up
def register_resource(self, resource):
        name = resource.name

        if name is not None:
            parts = self.NAME_SPLIT_RE.split(name)
            for part in parts:
                if not part.isidentifier() or keyword.iskeyword(part):
                    raise ValueError('Incorrect route name {!r}, '
                                     'the name should be a sequence of '
                                     'python identifiers separated '
                                     'by dash, dot or column'.format(name))
            if name in self._named_resources:
                raise ValueError('Duplicate {!r}, '
                                 'already handled by {!r}'
                                 .format(name, self._named_resources[name]))
            self._named_resources[name] = resource
        self._resources.append(resource) 
Example #10
Source File: import_statement.py    From Jandroid with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def value(self, value):
    value_parts = value.split('.')
    for value_part in value_parts:
      if keyword.iskeyword(value_part):
        raise ValueError('%s is a reserved keyword.' % value_part)

    # If we have too many children, cut the list down to size.
    # pylint: disable=attribute-defined-outside-init
    self._children = self._children[:len(value_parts)*2-1]

    # Update child nodes.
    for child, value_part in itertools.izip_longest(
        self._children[::2], value_parts):
      if child:
        # Modify existing children. This helps preserve comments and spaces.
        child.value = value_part
      else:
        # Add children as needed.
        self._children.append(snippet.TokenSnippet.Create(token.DOT, '.'))
        self._children.append(
            snippet.TokenSnippet.Create(token.NAME, value_part)) 
Example #11
Source File: import_statement.py    From Jandroid with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def alias(self, value):
    if keyword.iskeyword(value):
      raise ValueError('%s is a reserved keyword.' % value)

    if value:
       # pylint: disable=access-member-before-definition
      if len(self.children) < 3:
        # If we currently have no alias, add one.
         # pylint: disable=access-member-before-definition
        self.children.append(
            snippet.TokenSnippet.Create(token.NAME, 'as', (0, 1)))
         # pylint: disable=access-member-before-definition
        self.children.append(
            snippet.TokenSnippet.Create(token.NAME, value, (0, 1)))
      else:
        # We already have an alias. Just update the value.
        # pylint: disable=access-member-before-definition
        self.children[2].value = value
    else:
      # Removing the alias. Strip the "as foo".
      self.children = [self.children[0]] # pylint: disable=line-too-long, attribute-defined-outside-init 
Example #12
Source File: import_statement.py    From Jandroid with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def value(self, value):
    value_parts = value.split('.')
    for value_part in value_parts:
      if keyword.iskeyword(value_part):
        raise ValueError('%s is a reserved keyword.' % value_part)

    # If we have too many children, cut the list down to size.
    # pylint: disable=attribute-defined-outside-init
    self._children = self._children[:len(value_parts)*2-1]

    # Update child nodes.
    for child, value_part in itertools.izip_longest(
        self._children[::2], value_parts):
      if child:
        # Modify existing children. This helps preserve comments and spaces.
        child.value = value_part
      else:
        # Add children as needed.
        self._children.append(snippet.TokenSnippet.Create(token.DOT, '.'))
        self._children.append(
            snippet.TokenSnippet.Create(token.NAME, value_part)) 
Example #13
Source File: import_statement.py    From Jandroid with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def alias(self, value):
    if keyword.iskeyword(value):
      raise ValueError('%s is a reserved keyword.' % value)

    if value:
       # pylint: disable=access-member-before-definition
      if len(self.children) < 3:
        # If we currently have no alias, add one.
         # pylint: disable=access-member-before-definition
        self.children.append(
            snippet.TokenSnippet.Create(token.NAME, 'as', (0, 1)))
         # pylint: disable=access-member-before-definition
        self.children.append(
            snippet.TokenSnippet.Create(token.NAME, value, (0, 1)))
      else:
        # We already have an alias. Just update the value.
        # pylint: disable=access-member-before-definition
        self.children[2].value = value
    else:
      # Removing the alias. Strip the "as foo".
      self.children = [self.children[0]] # pylint: disable=line-too-long, attribute-defined-outside-init 
Example #14
Source File: import_statement.py    From Jandroid with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def value(self, value):
    value_parts = value.split('.')
    for value_part in value_parts:
      if keyword.iskeyword(value_part):
        raise ValueError('%s is a reserved keyword.' % value_part)

    # If we have too many children, cut the list down to size.
    # pylint: disable=attribute-defined-outside-init
    self._children = self._children[:len(value_parts)*2-1]

    # Update child nodes.
    for child, value_part in itertools.izip_longest(
        self._children[::2], value_parts):
      if child:
        # Modify existing children. This helps preserve comments and spaces.
        child.value = value_part
      else:
        # Add children as needed.
        self._children.append(snippet.TokenSnippet.Create(token.DOT, '.'))
        self._children.append(
            snippet.TokenSnippet.Create(token.NAME, value_part)) 
Example #15
Source File: import_statement.py    From Jandroid with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def module(self, value):
    if keyword.iskeyword(value):
      raise ValueError('%s is a reserved keyword.' % value)

    import_as_name = self._import_as_name
    if value == '*':
      # TODO: Implement this.
      raise NotImplementedError()
    else:
      if import_as_name:
        import_as_name.name = value
      else:
        # TODO: Implement this.
        raise NotImplementedError() 
Example #16
Source File: pythonrc.py    From pythonrc with MIT License 5 votes vote down vote up
def process_help_cmd(self, arg):
        if arg:
            if keyword.iskeyword(arg):
                self.push('help("{}")'.format(arg))
            elif arg in self.commands:
                self.commands[arg]('-h')
            else:
                self.push('help({})'.format(arg))
        else:
            print(cyan(self.__doc__).format(**config)) 
Example #17
Source File: pythonrc.py    From pythonrc with MIT License 5 votes vote down vote up
def _cmd_handler(self, line):
        matches = self.commands_re.match(line)
        if matches:
            command, args = matches.groups()
            line = self.commands[command](args)
        elif line.endswith(config['DOC_CMD']):
            if line.endswith(config['DOC_CMD']*2):
                # search for line in online docs
                # - strip off the '??' and the possible tab-completed
                # '(' or '.' and replace inner '.' with '+' to create the
                # query search string
                line = line.rstrip(config['DOC_CMD'] + '.(').replace('.', '+')
                webbrowser.open(config['DOC_URL'].format(sys=sys, term=line))
                line = ''
            else:
                line = line.rstrip(config['DOC_CMD'] + '.(')
                if not line:
                    line = 'dir()'
                elif keyword.iskeyword(line):
                    line = 'help("{}")'.format(line)
                else:
                    line = 'print({}.__doc__)'.format(line)
        elif config['AUTO_INDENT'] and (line.startswith(self.tab) or self._indent):
            if line.strip():
                # if non empty line with an indent, check if the indent
                # level has been changed
                leading_space = line[:line.index(line.lstrip()[0])]
                if self._indent != leading_space:
                    # indent level changed, update self._indent
                    self._indent = leading_space
            else:
                # - empty line, decrease indent
                self._indent = self._indent[:-len(self.tab)]
                line = self._indent
        elif line.startswith('%'):
            self.writeline('Y U NO LIKE ME?')
            return line
        return line or '' 
Example #18
Source File: compat.py    From aiohttp_apiset with Apache License 2.0 5 votes vote down vote up
def validate_name(self, name: str):
        """
        Fragment aiohttp.web_urldispatcher.UrlDispatcher#_reg_resource
        """
        parts = self.NAME_SPLIT_RE.split(name)
        for part in parts:
            if not part.isidentifier() or keyword.iskeyword(part):
                raise ValueError('Incorrect route name {!r}, '
                                 'the name should be a sequence of '
                                 'python identifiers separated '
                                 'by dash, dot or column'.format(name))
        if name in self._named_resources:
            raise ValueError('Duplicate {!r}, '
                             'already handled by {!r}'
                             .format(name, self._named_resources[name])) 
Example #19
Source File: format.py    From linter-pylama with MIT License 5 votes vote down vote up
def _opening_bracket(self, tokens, i):
        self._push_token(tokens[i][1], i)
        # Special case: ignore slices
        if tokens[i][1] == '[' and tokens[i+1][1] == ':':
            return

        if (i > 0 and (tokens[i-1][0] == tokenize.NAME and
                       not (keyword.iskeyword(tokens[i-1][1]))
                       or tokens[i-1][1] in _CLOSING_BRACKETS)):
            self._check_space(tokens, i, (_MUST_NOT, _MUST_NOT))
        else:
            self._check_space(tokens, i, (_IGNORE, _MUST_NOT)) 
Example #20
Source File: pycodestyle.py    From linter-pylama with MIT License 5 votes vote down vote up
def whitespace_before_parameters(logical_line, tokens):
    r"""Avoid extraneous whitespace.

    Avoid extraneous whitespace in the following situations:
    - before the open parenthesis that starts the argument list of a
      function call.
    - before the open parenthesis that starts an indexing or slicing.

    Okay: spam(1)
    E211: spam (1)

    Okay: dict['key'] = list[index]
    E211: dict ['key'] = list[index]
    E211: dict['key'] = list [index]
    """
    prev_type, prev_text, __, prev_end, __ = tokens[0]
    for index in range(1, len(tokens)):
        token_type, text, start, end, __ = tokens[index]
        if (token_type == tokenize.OP and
            text in '([' and
            start != prev_end and
            (prev_type == tokenize.NAME or prev_text in '}])') and
            # Syntax "class A (B):" is allowed, but avoid it
            (index < 2 or tokens[index - 2][1] != 'class') and
                # Allow "return (a.foo for a in range(5))"
                not keyword.iskeyword(prev_text)):
            yield prev_end, "E211 whitespace before '%s'" % text
        prev_type = token_type
        prev_text = text
        prev_end = end 
Example #21
Source File: codegen.py    From safrs with GNU General Public License v3.0 5 votes vote down vote up
def _convert_to_valid_identifier(name):
        assert name, "Identifier cannot be empty"
        if name[0].isdigit() or iskeyword(name):
            name = "_" + name
        elif name == "metadata":
            name = "metadata_"

        return _re_invalid_identifier.sub("_", name) 
Example #22
Source File: names.py    From GrowthNodes with GNU General Public License v3.0 5 votes vote down vote up
def toVariableName(name):
    variable = re.sub("\W+", "", name)
    if keyword.iskeyword(variable): variable += "_"
    if variable == "": variable = "_"
    return variable 
Example #23
Source File: htmlizer.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def printtoken(self, type, token, sCoordinates, eCoordinates, line):
        if hasattr(tokenize, "ENCODING") and type == tokenize.ENCODING:
            self.encoding = token
            return

        (srow, scol) = sCoordinates
        (erow, ecol) = eCoordinates
        if self.currentLine < srow:
            self.writer('\n'*(srow-self.currentLine))
            self.currentLine, self.currentCol = srow, 0
        self.writer(' '*(scol-self.currentCol))
        if self.lastIdentifier:
            type = "identifier"
            self.parameters = 1
        elif type == tokenize.NAME:
            if keyword.iskeyword(token):
                type = 'keyword'
            else:
                if self.parameters:
                    type = 'parameter'
                else:
                    type = 'variable'
        else:
            type = tokenize.tok_name.get(type).lower()
        self.writer(token, type)
        self.currentCol = ecol
        self.currentLine += token.count('\n')
        if self.currentLine != erow:
            self.currentCol = 0
        self.lastIdentifier = token in ('def', 'class')
        if token == ':':
            self.parameters = 0 
Example #24
Source File: pycodestyle.py    From PyDev.Debugger with Eclipse Public License 1.0 5 votes vote down vote up
def whitespace_before_parameters(logical_line, tokens):
    r"""Avoid extraneous whitespace.

    Avoid extraneous whitespace in the following situations:
    - before the open parenthesis that starts the argument list of a
      function call.
    - before the open parenthesis that starts an indexing or slicing.

    Okay: spam(1)
    E211: spam (1)

    Okay: dict['key'] = list[index]
    E211: dict ['key'] = list[index]
    E211: dict['key'] = list [index]
    """
    prev_type, prev_text, __, prev_end, __ = tokens[0]
    for index in range(1, len(tokens)):
        token_type, text, start, end, __ = tokens[index]
        if (token_type == tokenize.OP and
            text in '([' and
            start != prev_end and
            (prev_type == tokenize.NAME or prev_text in '}])') and
            # Syntax "class A (B):" is allowed, but avoid it
            (index < 2 or tokens[index - 2][1] != 'class') and
                # Allow "return (a.foo for a in range(5))"
                not keyword.iskeyword(prev_text)):
            yield prev_end, "E211 whitespace before '%s'" % text
        prev_type = token_type
        prev_text = text
        prev_end = end 
Example #25
Source File: autopep8.py    From PyDev.Debugger with Eclipse Public License 1.0 5 votes vote down vote up
def is_keyword(self):
        return keyword.iskeyword(self._atom.token_string) 
Example #26
Source File: pt2html.py    From pyx with GNU General Public License v2.0 5 votes vote down vote up
def tokeneater(self, toktype, toktext, xxx_todo_changeme, xxx_todo_changeme1, line):
        (srow, scol) = xxx_todo_changeme
        (erow, ecol) = xxx_todo_changeme1
        if toktype == token.ERRORTOKEN:
            raise RuntimeError("ErrorToken occured")
        if toktype in [token.NEWLINE, tokenize.NL]:
            self.output.write('\n')
            self.col = 0
        else:
            # map token type to a color group
            if token.LPAR <= toktype and toktype <= token.OP:
                toktype = token.OP
            elif toktype == token.NAME and keyword.iskeyword(toktext):
                toktype = _KEYWORD

            # restore whitespace
            assert scol >= self.col
            self.output.write(" "*(scol-self.col))

            try:
                tokclass = tokclasses[toktype]
            except KeyError:
                tokclass = None
            if self.tokclass is not None and tokclass != self.tokclass:
                self.output.write('</span>')
            if tokclass is not None and tokclass != self.tokclass:
                self.output.write('<span class="%s">' % tokclass)
            self.output.write(cgi.escape(toktext))
            self.tokclass = tokclass

            # calculate new column position
            self.col = scol + len(toktext)
            newline = toktext.rfind("\n")
            if newline != -1:
                self.col = len(toktext) - newline - 1 
Example #27
Source File: python.py    From Computable with MIT License 5 votes vote down vote up
def python(expr, **settings):
    """Return Python interpretation of passed expression
    (can be passed to the exec() function without any modifications)"""

    printer = PythonPrinter(settings)
    exprp = printer.doprint(expr)

    result = ''
    # Returning found symbols and functions
    renamings = {}
    for symbolname in printer.symbols:
        newsymbolname = symbolname
        # Escape symbol names that are reserved python keywords
        if kw.iskeyword(newsymbolname):
            while True:
                newsymbolname += "_"
                if (newsymbolname not in printer.symbols and
                        newsymbolname not in printer.functions):
                    renamings[sympy.Symbol(
                        symbolname)] = sympy.Symbol(newsymbolname)
                    break
        result += newsymbolname + ' = Symbol(\'' + symbolname + '\')\n'

    for functionname in printer.functions:
        newfunctionname = functionname
        # Escape function names that are reserved python keywords
        if kw.iskeyword(newfunctionname):
            while True:
                newfunctionname += "_"
                if (newfunctionname not in printer.symbols and
                        newfunctionname not in printer.functions):
                    renamings[sympy.Function(
                        functionname)] = sympy.Function(newfunctionname)
                    break
        result += newfunctionname + ' = Function(\'' + functionname + '\')\n'

    if not len(renamings) == 0:
        exprp = expr.subs(renamings)
    result += 'e = ' + printer._str(exprp)
    return result 
Example #28
Source File: expr.py    From recruit with Apache License 2.0 5 votes vote down vote up
def visit(self, node, **kwargs):
        if isinstance(node, string_types):
            clean = self.preparser(node)
            try:
                node = ast.fix_missing_locations(ast.parse(clean))
            except SyntaxError as e:
                from keyword import iskeyword
                if any(iskeyword(x) for x in clean.split()):
                    e.msg = ("Python keyword not valid identifier"
                             " in numexpr query")
                raise e

        method = 'visit_' + node.__class__.__name__
        visitor = getattr(self, method)
        return visitor(node, **kwargs) 
Example #29
Source File: PyColorize.py    From Computable with MIT License 5 votes vote down vote up
def __call__(self, toktype, toktext, start_pos, end_pos, line):
        """ Token handler, with syntax highlighting."""
        (srow,scol) = start_pos
        (erow,ecol) = end_pos
        colors = self.colors
        owrite = self.out.write

        # line separator, so this works across platforms
        linesep = os.linesep

        # calculate new positions
        oldpos = self.pos
        newpos = self.lines[srow] + scol
        self.pos = newpos + len(toktext)

        # send the original whitespace, if needed
        if newpos > oldpos:
            owrite(self.raw[oldpos:newpos])

        # skip indenting tokens
        if toktype in [token.INDENT, token.DEDENT]:
            self.pos = newpos
            return

        # map token type to a color group
        if token.LPAR <= toktype and toktype <= token.OP:
            toktype = token.OP
        elif toktype == token.NAME and keyword.iskeyword(toktext):
            toktype = _KEYWORD
        color = colors.get(toktype, colors[_TEXT])

        #print '<%s>' % toktext,    # dbg

        # Triple quoted strings must be handled carefully so that backtracking
        # in pagers works correctly. We need color terminators on _each_ line.
        if linesep in toktext:
            toktext = toktext.replace(linesep, '%s%s%s' %
                                      (colors.normal,linesep,color))

        # send text
        owrite('%s%s%s' % (color,toktext,colors.normal)) 
Example #30
Source File: utils.py    From altair with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def is_valid_identifier(var, allow_unicode=False):
    """Return true if var contains a valid Python identifier

    Parameters
    ----------
    val : string
        identifier to check
    allow_unicode : bool (default: False)
        if True, then allow Python 3 style unicode identifiers.
    """
    flags = re.UNICODE if allow_unicode else re.ASCII
    is_valid = re.match(r"^[^\d\W]\w*\Z", var, flags)
    return is_valid and not keyword.iskeyword(var)