Skip to content

Commit

Permalink
pylint fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
chriddyp committed Jan 3, 2018
1 parent c4d60e3 commit 2c07f19
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 71 deletions.
1 change: 1 addition & 0 deletions dash/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __getattr__(self, key):
# to conform with __getattr__ spec
raise AttributeError(key)

# pylint: disable=inconsistent-return-statements
def first(self, *names):
for name in names:
value = self.get(name)
Expand Down
59 changes: 32 additions & 27 deletions dash/dash.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import pkgutil
import warnings
from flask import Flask, Response
from flask_compress import Compress
import flask
from flask_compress import Compress
import plotly

import dash_renderer
Expand All @@ -17,16 +17,17 @@
from ._utils import AttributeDict as _AttributeDict


# pylint: disable=too-many-instance-attributes
class Dash(object):
def __init__(
self,
name=None,
server=None,
static_folder=None,
url_base_pathname='/',
**kwargs
):

self,
name=None,
server=None,
static_folder=None,
url_base_pathname='/',
**kwargs):

# pylint-disable: too-many-instance-attributes
if 'csrf_protect' in kwargs:
warnings.warn('''
`csrf_protect` is no longer used,
Expand Down Expand Up @@ -58,12 +59,13 @@ def __init__(
self.registered_paths = {}

# urls
def add_url(name, view_func, methods=['GET']):

def add_url(name, view_func, methods=('GET',)):
self.server.add_url_rule(
name,
view_func=view_func,
endpoint=name,
methods=methods
methods=list(methods)
)

add_url(
Expand All @@ -77,18 +79,16 @@ def add_url(name, view_func, methods=['GET']):

add_url(
'{}_dash-update-component'.format(
self.config['routes_pathname_prefix']
),
self.config['routes_pathname_prefix']),
self.dispatch,
['POST'])

add_url((
'{}_dash-component-suites'
'/<string:package_name>'
'/<path:path_in_package_dist>').format(
self.config['routes_pathname_prefix']
),
self.serve_component_suites)
self.config['routes_pathname_prefix']),
self.serve_component_suites)

add_url(
'{}_dash-routes'.format(self.config['routes_pathname_prefix']),
Expand Down Expand Up @@ -133,6 +133,7 @@ def layout(self, value):
self._layout = value

layout_value = self._layout_value()
# pylint: disable=protected-access
self.css._update_layout(layout_value)
self.scripts._update_layout(layout_value)
self._collect_and_register_resources(
Expand Down Expand Up @@ -223,6 +224,7 @@ def _generate_scripts_html(self):
# scripts have rendered.
# The rest of the scripts can just be loaded after React but before
# dash renderer.
# pylint: disable=protected-access
srcs = self._collect_and_register_resources(
self.scripts._resources._filter_resources(
dash_renderer._js_dist_dependencies
Expand Down Expand Up @@ -275,7 +277,7 @@ def serve_component_suites(self, package_name, path_in_package_dist):
mimetype=mimetype
)

def index(self, *args, **kwargs):
def index(self):
scripts = self._generate_scripts_html()
css = self._generate_css_dist_html()
config = self._generate_config_html()
Expand Down Expand Up @@ -315,13 +317,15 @@ def dependencies(self):
} for k, v in list(self.callback_map.items())
])

# pylint: disable=unused-argument, no-self-use
def react(self, *args, **kwargs):
raise exceptions.DashException(
'Yo! `react` is no longer used. \n'
'Use `callback` instead. `callback` has a new syntax too, '
'so make sure to call `help(app.callback)` to learn more.')

def _validate_callback(self, output, inputs, state, events):
# pylint: disable=too-many-branches
layout = self._cached_layout or self._layout_value()

if (layout is None and
Expand All @@ -337,10 +341,10 @@ def _validate_callback(self, output, inputs, state, events):
`app.config['suppress_callback_exceptions']=True`
'''.replace(' ', ''))

for args, object, name in [([output], Output, 'Output'),
(inputs, Input, 'Input'),
(state, State, 'State'),
(events, Event, 'Event')]:
for args, obj, name in [([output], Output, 'Output'),
(inputs, Input, 'Input'),
(state, State, 'State'),
(events, Event, 'Event')]:

if not isinstance(args, list):
raise exceptions.IncorrectTypeException(
Expand All @@ -350,7 +354,7 @@ def _validate_callback(self, output, inputs, state, events):
))

for arg in args:
if not isinstance(arg, object):
if not isinstance(arg, obj):
raise exceptions.IncorrectTypeException(
'The {} argument `{}` is '
'not of type `dash.{}`.'.format(
Expand Down Expand Up @@ -402,8 +406,8 @@ def _validate_callback(self, output, inputs, state, events):
arg.component_id,
arg.component_property,
arg.component_id,
component.available_properties
).replace(' ', ''))
component.available_properties)\
.replace(' ', ''))

if (hasattr(arg, 'component_event') and
arg.component_event not in
Expand All @@ -418,10 +422,10 @@ def _validate_callback(self, output, inputs, state, events):
arg.component_id,
arg.component_event,
arg.component_id,
component.available_events
).replace(' ', ''))
component.available_events)\
.replace(' ', ''))

if len(state) > 0 and len(events) == 0 and len(inputs) == 0:
if state and not events and not inputs:
raise exceptions.MissingEventsException('''
This callback has {} `State` {}
but no `Input` elements or `Event` elements.\n
Expand Down Expand Up @@ -466,6 +470,7 @@ def _validate_callback(self, output, inputs, state, events):
# the dropdown.
# TODO - Check this map for recursive or other ill-defined non-tree
# relationships
# pylint: disable=dangerous-default-value
def callback(self, output, inputs=[], state=[], events=[]):
self._validate_callback(output, inputs, state, events)

Expand Down
7 changes: 4 additions & 3 deletions dash/dependencies.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
# pylint: disable=old-style-class, too-few-public-methods
class Output:
def __init__(self, component_id, component_property):
self.component_id = component_id
self.component_property = component_property


# pylint: disable=old-style-class, too-few-public-methods
class Input:
def __init__(self, component_id, component_property):
self.component_id = component_id
self.component_property = component_property


# pylint: disable=old-style-class, too-few-public-methods
class State:
def __init__(self, component_id, component_property):
self.component_id = component_id
self.component_property = component_property


# pylint: disable=old-style-class, too-few-public-methods
class Event:
def __init__(self, component_id, component_event):
self.component_id = component_id
Expand Down
81 changes: 42 additions & 39 deletions dash/development/base_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,45 @@ def is_number(s):
return False


def _check_if_has_indexable_children(item):
if (not hasattr(item, 'children') or
(not isinstance(item.children, Component) and
not isinstance(item.children, collections.MutableSequence))):

raise KeyError


class Component(collections.MutableMapping):
def __init__(self, **kwargs):
# pylint: disable=super-init-not-called
for k, v in list(kwargs.items()):
if k not in self._prop_names:
if k not in self._prop_names: # pylint: disable=no-member
# TODO - What's the right exception here?
raise Exception(
'Unexpected keyword argument `{}`'.format(k) +
'\nAllowed arguments: {}'.format(
', '.join(sorted(self._prop_names))
', '.join(sorted(self._prop_names)) # pylint: disable=no-member
)
)
setattr(self, k, v)

def to_plotly_json(self):
as_json = {
'props': {p: getattr(self, p)
for p in self._prop_names
for p in self._prop_names # pylint: disable=no-member
if hasattr(self, p)},
'type': self._type,
'namespace': self._namespace
'type': self._type, # pylint: disable=no-member
'namespace': self._namespace # pylint: disable=no-member
}

return as_json

def _check_if_has_indexable_children(self, item):
if (not hasattr(item, 'children') or
(not isinstance(item.children, Component) and
not isinstance(item.children, collections.MutableSequence))):

raise KeyError

# pylint: disable=too-many-branches, too-many-return-statements, redefined-builtin, inconsistent-return-statements
def _get_set_or_delete(self, id, operation, new_item=None):
self._check_if_has_indexable_children(self)
_check_if_has_indexable_children(self)

# pylint: disable=access-member-before-definition, attribute-defined-outside-init
if isinstance(self.children, Component):
if getattr(self.children, 'id', None) is not None:
# Woohoo! It's the item that we're looking for
Expand Down Expand Up @@ -110,7 +115,7 @@ def _get_set_or_delete(self, id, operation, new_item=None):
# - __iter__
# - __len__

def __getitem__(self, id):
def __getitem__(self, id): # pylint: disable=redefined-builtin
"""Recursively find the element with the given ID through the tree
of children.
"""
Expand All @@ -119,11 +124,11 @@ def __getitem__(self, id):
# or a list of components.
return self._get_set_or_delete(id, 'get')

def __setitem__(self, id, item):
def __setitem__(self, id, item): # pylint: disable=redefined-builtin
"""Set an element by its ID."""
return self._get_set_or_delete(id, 'set', item)

def __delitem__(self, id):
def __delitem__(self, id): # pylint: disable=redefined-builtin
"""Delete items by ID in the tree of children."""
return self._get_set_or_delete(id, 'delete')

Expand All @@ -139,7 +144,7 @@ def traverse(self):

# children is a list of components
elif isinstance(children, collections.MutableSequence):
for i in children:
for i in children: # pylint: disable=not-an-iterable
yield i

if isinstance(i, Component):
Expand Down Expand Up @@ -177,7 +182,7 @@ def __len__(self):
return length


def generate_class(typename, props, description, namespace):
def generate_class(typename, props, description, namespace): # pylint: disable=unused-argument
# Dynamically generate classes to have nicely formatted docstrings,
# keyword arguments, and repr
# Insired by http://jameso.be/2013/08/06/namedtuple.html
Expand Down Expand Up @@ -229,28 +234,28 @@ def __repr__(self):
repr(getattr(self, self._prop_names[0], None)) + ')')
'''

filtered_props = reorder_props(filter_props(props))
list_of_valid_keys = repr(list(filtered_props.keys()))
docstring = create_docstring(
filtered_props = reorder_props(filter_props(props)) # pylint: disable=unused-variable
list_of_valid_keys = repr(list(filtered_props.keys())) # pylint: disable=unused-variable
docstring = create_docstring( # pylint: disable=unused-variable
typename,
filtered_props,
parse_events(props),
description
)
events = '[' + ', '.join(parse_events(props)) + ']'
events = '[' + ', '.join(parse_events(props)) + ']' # pylint: disable=unused-variable
if 'children' in props:
default_argtext = 'children=None, **kwargs'
argtext = 'children=children, **kwargs'
default_argtext = 'children=None, **kwargs' # pylint: disable=unused-variable
argtext = 'children=children, **kwargs' # pylint: disable=unused-variable
else:
default_argtext = '**kwargs'
argtext = '**kwargs'
default_argtext = '**kwargs' # pylint: disable=unused-variable
argtext = '**kwargs' # pylint: disable=unused-variable

required_args = required_props(props)
required_args = required_props(props) # pylint: disable=unused-variable

d = c.format(**locals())

scope = {'Component': Component}
exec(d, scope)
exec(d, scope) # pylint: disable=exec-used
result = scope[typename]
return result

Expand Down Expand Up @@ -350,7 +355,7 @@ def js_to_py_type(type_object):
])),

# React's PropTypes.arrayOf
'arrayOf': lambda: 'list'.format(
'arrayOf': lambda: 'list'.format( # pylint: disable=too-many-format-args
'of {}s'.format(js_to_py_type(type_object['value']))
if js_to_py_type(type_object['value']) != ''
else ''
Expand Down Expand Up @@ -387,8 +392,7 @@ def js_to_py_type(type_object):
return ''
if js_type_name in js_to_py_types:
return js_to_py_types[js_type_name]()
else:
return ''
return ''


def argument_doc(arg_name, type_object, required, description):
Expand All @@ -404,12 +408,11 @@ def argument_doc(arg_name, type_object, required, description):
is_required='required' if required else 'optional'
)

else:
return '{name} ({type}{is_required}){description}'.format(
name=arg_name,
type='{}; '.format(py_type_name) if py_type_name else '',
description=(
': {}'.format(description) if description != '' else ''
),
is_required='required' if required else 'optional'
)
return '{name} ({type}{is_required}){description}'.format(
name=arg_name,
type='{}; '.format(py_type_name) if py_type_name else '',
description=(
': {}'.format(description) if description != '' else ''
),
is_required='required' if required else 'optional'
)
Loading

0 comments on commit 2c07f19

Please sign in to comment.