def __init__(self, namespace: str, is_core: bool = False) -> None:
# TODO add search base paths parameter
if not namespace.isidentifier():
raise ValueError("Invalid plugin namespace."
f" {namespace!r} contains invalid symbol(s).")
if keyword.iskeyword(namespace):
raise ValueError("Invalid plugin namespace."
f" {namespace!r} is a built-in keyword.")
self.namespace = namespace
if f'{__package__}.{namespace}' in sys.modules:
raise RuntimeError(f"Expected '{__package__}.{namespace}' in `sys.modules` to be unset"
" but it was not")
setattr(sys.modules[__package__], namespace, self)
sys.modules[f'{__package__}.{namespace}'] = self
if is_core:
# just search in one single path
self.plugin_search_paths = [pathlib.Path(self._shanghai_base_path, namespace)]
else:
self.plugin_search_paths = [pathlib.Path(base_path, namespace)
for base_path in self.PLUGIN_SEARCH_BASE_PATHS]
self.plugin_registry = {}
self.logger = get_default_logger()
python类iskeyword()的实例源码
def check_project_name(parser, project_name):
"""Perform checks for the given project name.
Checks:
- not a reserved Python keyword.
- not already in use by another Python package/module.
"""
if iskeyword(project_name):
parser.error("'{project_name}' can not be a reserved Python keyword.".format(project_name=project_name))
try:
__import__(project_name)
except ImportError:
pass
else:
parser.error("'{project_name}' conflicts with the name of an existing "
"Python module and cannot be used as a project "
"name. Please try another name.".format(project_name=project_name))
def _normalize(args):
# type: (Dict[str, Any]) -> Generator[Tuple[str, str, Any], None, None]
"""Yield a 3-tuple containing the key, a normalized key, and the value.
Args:
args: The arguments parsed by docopt.
Yields:
A 3-tuple that contains the docopt parameter name, the parameter name
normalized to be a valid python identifier, and the value assigned to
the parameter.
"""
for k, v in six.iteritems(args):
nk = re.sub(r'\W|^(?=\d)', '_', k).strip('_').lower()
do_not_shadow = dir(six.moves.builtins) # type: ignore
if keyword.iskeyword(nk) or nk in do_not_shadow:
nk += '_'
_LOGGER.debug('Normalized "%s" to "%s".', k, nk)
yield k, nk, v
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))
def _parse_path(self, path=None):
if not path:
return ()
if isinstance(path, six.string_types):
separator = self.settings.str_path_separator
clean_path = []
for part in path.split(separator):
if part.endswith('_') and keyword.iskeyword(part[:-1]):
clean_path.append(part[:-1])
else:
clean_path.append(part)
clean_path = tuple(clean_path)
else:
clean_path = path
# This is to raise NotFound in case path doesn't exist and to have it
# handled by not_found hook callbacks.
self._get_by_key(path)
return clean_path
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
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
def pythonic_names():
original_get_attribute = ecore.ENamedElement.__getattribute__
def get_attribute(self, name):
value = original_get_attribute(self, name)
if name == 'name':
while keyword.iskeyword(value):
# appending underscores is a typical way of removing name clashes in Python:
value += '_'
return value
ecore.ENamedElement.__getattribute__ = get_attribute
yield
ecore.ENamedElement.__getattribute__ = original_get_attribute
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
def _find_primary_without_dot_start(self, offset):
"""It tries to find the undotted primary start
It is different from `self._get_atom_start()` in that it
follows function calls, too; such as in ``f(x)``.
"""
last_atom = offset
offset = self._find_last_non_space_char(last_atom)
while offset > 0 and self.code[offset] in ')]':
last_atom = self._find_parens_start(offset)
offset = self._find_last_non_space_char(last_atom - 1)
if offset >= 0 and (self.code[offset] in '"\'})]' or
self._is_id_char(offset)):
atom_start = self._find_atom_start(offset)
if not keyword.iskeyword(self.code[atom_start:offset + 1]):
return atom_start
return last_atom
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.lookup_concrete(var_tvar) == ass_node.value.elts[0].type_constraints.type
def is_valid_module_path_component(token):
"Validate strings to be used when importing modules dynamically."
return not token.startswith('_') and not keyword.iskeyword(token) and \
all( ( (x.isalnum() or x == '_') for x in token ) )
def name_to_py(name):
result = name.replace("-", "_")
result = result.lower()
if keyword.iskeyword(result) or result in dir(builtins):
result += "_"
return result
def fix_method_name(name):
"""Fix method names to avoid reserved word conflicts.
Args:
name: string, method name.
Returns:
The name with a '_' prefixed if the name is a reserved word.
"""
if keyword.iskeyword(name) or name in RESERVED_WORDS:
return name + '_'
else:
return name
def _positional_rename_invalid_identifiers(field_names):
names_out = list(field_names)
for index, name in enumerate(field_names):
if (not all(c.isalnum() or c == '_' for c in name)
or keyword.iskeyword(name)
or not name
or name[0].isdigit()
or name.startswith('_')):
names_out[index] = 'field_%d_' % index
return names_out
def to_python(self, name):
name = name.replace('-', '_')
if name.endswith('_'):
name = name[:-1]
if keyword.iskeyword(name):
name += '_'
return name
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
def fix_method_name(name):
"""Fix method names to avoid reserved word conflicts.
Args:
name: string, method name.
Returns:
The name with a '_' prefixed if the name is a reserved word.
"""
if keyword.iskeyword(name) or name in RESERVED_WORDS:
return name + '_'
else:
return name
def _check_related_name_is_valid(self):
import re
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 six.PY3:
if not related_name.isidentifier():
is_valid_id = False
else:
if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*\Z', related_name):
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 []
def fix_method_name(name):
"""Fix method names to avoid reserved word conflicts.
Args:
name: string, method name.
Returns:
The name with a '_' prefixed if the name is a reserved word.
"""
if keyword.iskeyword(name) or name in RESERVED_WORDS:
return name + '_'
else:
return name
def MakePublicAttributeName(className, is_global = False):
# Given a class attribute that needs to be public, convert it to a
# reasonable name.
# Also need to be careful that the munging doesnt
# create duplicates - eg, just removing a leading "_" is likely to cause
# a clash.
# if is_global is True, then the name is a global variable that may
# overwrite a builtin - eg, "None"
if className[:2]=='__':
return demunge_leading_underscores(className)
elif className == 'None':
# assign to None is evil (and SyntaxError in 2.4, even though
# iskeyword says False there) - note that if it was a global
# it would get picked up below
className = 'NONE'
elif iskeyword(className):
# most keywords are lower case (except True, False etc in py3k)
ret = className.capitalize()
# but those which aren't get forced upper.
if ret == className:
ret = ret.upper()
return ret
elif is_global and hasattr(__builtins__, className):
# builtins may be mixed case. If capitalizing it doesn't change it,
# force to all uppercase (eg, "None", "True" become "NONE", "TRUE"
ret = className.capitalize()
if ret==className: # didn't change - force all uppercase.
ret = ret.upper()
return ret
# Strip non printable chars
return ''.join([char for char in className if char in valid_identifier_chars])
# Given a default value passed by a type library, return a string with
# an appropriate repr() for the type.
# Takes a raw ELEMDESC and returns a repr string, or None
# (NOTE: The string itself may be '"None"', which is valid, and different to None.
# XXX - To do: Dates are probably screwed, but can they come in?
def __init__(self, mapping):
self.__data = {}
for key, value in mapping.items():
if keyword.iskeyword(key): # <1>
key += '_'
self.__data[key] = value
# END EXPLORE1
def improved_rlcompleter(self):
"""Enhances the default rlcompleter
The function enhances the default rlcompleter by also doing
pathname completion and module name completion for import
statements. Additionally, it inserts a tab instead of attempting
completion if there is no preceding text.
"""
completer = rlcompleter.Completer(namespace=self.locals)
# - remove / from the delimiters to help identify possibility for path completion
readline.set_completer_delims(readline.get_completer_delims().replace('/', ''))
modlist = frozenset(name for _, name, _ in pkgutil.iter_modules())
def complete_wrapper(text, state):
line = readline.get_line_buffer().strip()
if line == '':
return None if state > 0 else self.tab
if state == 0:
if line.startswith(('import', 'from')):
completer.matches = [name for name in modlist if name.startswith(text)]
else:
match = completer.complete(text, state)
if match is None and '/' in text:
completer.matches = glob.glob(text+'*')
try:
match = completer.matches[state]
return '{}{}'.format(match, ' ' if keyword.iskeyword(match) else '')
except IndexError:
return None
return complete_wrapper
def raw_input(self, prompt=''):
"""Read the input and delegate if necessary.
"""
line = InteractiveConsole.raw_input(self, prompt)
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 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 ''
def attr_str(attr_name):
# type: (str) -> str
"""Gets the string to use when accessing an attribute on an object.
Handles case where the attribute name collides with a keyword and would
therefore be illegal to access with dot notation.
"""
if keyword.iskeyword(attr_name):
return 'getattr(obj, "{0}")'.format(attr_name)
return 'obj.{0}'.format(attr_name)
def load_plugin(self, identifier: str, *,
dependency_path: Iterable[str] = (),
is_core: bool = False,
) -> Plugin:
if not identifier.isidentifier():
raise ValueError(f"Invalid plugin name. {identifier!r} contains invalid symbol(s).")
if keyword.iskeyword(identifier):
raise ValueError(f"Invalid plugin name. {identifier!r} is a built-in keyword.")
if identifier in self.plugin_registry:
if not dependency_path:
self.logger.warn(f"Plugin {identifier!r} already exists")
return self.plugin_registry[identifier]
for search_path in self.plugin_search_paths:
try:
module_path = self._find_module_path(search_path, identifier)
except OSError:
continue
else:
break
else:
raise FileNotFoundError(
f"Could not find plugin {identifier!r} in any of the search paths:"
+ "".join(f'\n {path!s}' for path in self.plugin_search_paths)
)
plugin = self._load_plugin_as_module(module_path, identifier,
dependency_path=dependency_path)
self._register_plugin(plugin)
return plugin
def MakePublicAttributeName(className, is_global = False):
# Given a class attribute that needs to be public, convert it to a
# reasonable name.
# Also need to be careful that the munging doesnt
# create duplicates - eg, just removing a leading "_" is likely to cause
# a clash.
# if is_global is True, then the name is a global variable that may
# overwrite a builtin - eg, "None"
if className[:2]=='__':
return demunge_leading_underscores(className)
elif className == 'None':
# assign to None is evil (and SyntaxError in 2.4, even though
# iskeyword says False there) - note that if it was a global
# it would get picked up below
className = 'NONE'
elif iskeyword(className):
# most keywords are lower case (except True, False etc in py3k)
ret = className.capitalize()
# but those which aren't get forced upper.
if ret == className:
ret = ret.upper()
return ret
elif is_global and hasattr(__builtins__, className):
# builtins may be mixed case. If capitalizing it doesn't change it,
# force to all uppercase (eg, "None", "True" become "NONE", "TRUE"
ret = className.capitalize()
if ret==className: # didn't change - force all uppercase.
ret = ret.upper()
return ret
# Strip non printable chars
return ''.join([char for char in className if char in valid_identifier_chars])
# Given a default value passed by a type library, return a string with
# an appropriate repr() for the type.
# Takes a raw ELEMDESC and returns a repr string, or None
# (NOTE: The string itself may be '"None"', which is valid, and different to None.
# XXX - To do: Dates are probably screwed, but can they come in?
def TypeView(self, name, obj):
""" return a Type-specific view which is never used
for unqiue (final) completion.
"""
if not keyword.iskeyword(name) and self.config.typesize:
if inspect.isclass(obj) and issubclass(obj, Exception):
name='<exc>%s' % name
elif type(obj) in self.abbdict:
name='<%s>%s' % (self.abbdict[type(obj)], name)
if callable(obj):
name=name+format_callable_signature(obj)
return name
def TypeCompletion(self, name, obj):
""" determines natural completion characters
for the given obj. For an appropriate
definition of 'natural' :-)
"""
if callable(obj):
if format_callable_signature(obj).endswith('()'):
return "()"
return "("
if inspect.ismodule(obj):
return '.'
if keyword.iskeyword(name):
return ' '
return ''
def doculines(self, name, obj, keywidth):
""" show documentation for one match trimmed to
a few lines (currently one).
"""
if keyword.iskeyword(name):
objdoc = '<python keyword>'
else:
objdoc = docstring(obj)
if not objdoc:
objdoc = ': %s, type: %s' % (obj,type(obj))
objdoc = self.condense_rex.sub('. ',objdoc.strip())
# cut out part of c-signature in doctring
try:
inspect.getargspec(obj)
except TypeError:
i = objdoc.find('->')
if i!=-1:
objdoc = objdoc[i:]
namedoc = self.TypeView(name,obj)
namedoc = namedoc.ljust(keywidth)+' '
line = namedoc + objdoc
width = self.config.terminalwidth-4
return [line[:width-1].ljust(width-1)]