flexxui / flexx Goto Github PK
View Code? Open in Web Editor NEWWrite desktop and web apps in pure Python
Home Page: http://flexx.readthedocs.io
License: BSD 2-Clause "Simplified" License
Write desktop and web apps in pure Python
Home Page: http://flexx.readthedocs.io
License: BSD 2-Clause "Simplified" License
Would help get to #19.
In particular, a parser that generates commonast. My best bet is on using something based off libpy2to3. pyjs has one. There is also a js-based Python parser. Pygments has a good tokenizer, on top of which we could build an ast producer. Also see this discussion: davidhalter/jedi#630
It seems this is because a canvas size behaves differently from other HTML elements. I think this can be fixed by nesting the canvas in a div.
Pre: the difference in behaviour of operators is the main JS that "leaks" through in PyScript. Fixing this, would make PyScript even more Pythonic.
Con: this would require a function call everywhere where an operator (like add and mul) is used (like in Batavia: https://github.com/pybee/batavia/blob/master/batavia/utils.js#L210). In tight loops this hurts performance.
Idea: Maybe implement that, and allow a context manager where we have more raw JS (disabling PyScript's smart stuff).
A request to add 2.7 support, which came from here ( bokeh/bokeh#3121 (comment) ).
(the free tier gives you 12 months free use (720 hours, which is fulltime) of a simple server.)
Do this soon, so that it still can be changed.
Pypy is slow to startup, so to make the travis build faster, it will probably help to dont run tests on pypy that spawn a new Python interpreter (as in the import tests, cli test, ...).
There is room for optimizations to reduce the memory footprint.
https://elements.polymer-project.org/
http://webcomponents.org/
Might give flexx free widgets.
This looks like a great project. Looking forward to using it. Just one question. Have you considered using something like Brython for the JavaScript handling instead of writing your own implementation? Having a Python3-only solutions seems fine to me. Do you want to avoid too many dependency? Or does Brython not meet your needs?
The example hello_world.py
fails:
Traceback (most recent call last):
File "hello_world.py", line 6, in <module>
from flexx import app, ui
File "/Users/mike/Dev/flexx/flexx/ui/__init__.py", line 90, in <module>
from ._iframe import IFrame
Traceback (most recent call last):
File "hello_world.py", line 6, in <module>
from flexx import app, ui
File "/Users/mike/Dev/flexx/flexx/ui/__init__.py", line 90, in <module>
from ._iframe import IFrame
Looks like lexx/ui/_iframe.py
has not been checked in yet. Commenting out the line from ._iframe import IFrame
fixes the problem.
https://github.com/ReactiveX/RxPY
Have you seen this? Maybe better to use that than maintain your own FRP framework.
There is a memory leak, because the demo server http://52.21.93.28:8000/ keeps accumulating RAM usage as it has handled more sessions.
We need a simple way to configurarion some aspects of Flexx. A unified approach so that each config option can be set:
python setup.py sdist bdist_wheel --universal
twine upload dist/*
We should have tests to validate visual output of widgets and apps. These should be runnable both locally and on Travis. We'd want to be able to run the tests for each browser that we support. On CI it might be ok to do only FF, but would be nice to do all.
General options:
flexx.webruntime
does, but with more control. First time I tried it did not catch FF. Needs exes to be on PATH. Easy support for grabbing screenshots. For chrome it needs a chromedriver.CI options:
Eventually we'd want to test for several browsers in CI using saucelabs. For the short term, we should aim for a solution that can be run locally and also on Travis.
Approach:
The margin
property of e.g. the HBox was taken from Qt layouts. However, its implemented with css-padding, so the term is confusing, especially to web devs. We should rename.
Wrote summary and ideas down here: https://github.com/zoofIO/flexx/wiki/Functional-Reactive-Programming
This issue should be more about API design and implementation.
Whatever API we come up with, we must be able to apply it to PyScript and have it work in JS too.
Input signals are quite similar to properties/traits. However, if we want to allow access to the signal object, we cannot do:
> foo.title = 'new title'
> foo.title
new title # -> should be <signal instance at 0x123>
Solutions:
foo.signals.title
. Ugh. Again, asymmetry with plain signal objects (not on a HasSignals
instance).foo.title('new title')
sets the signal. I need to get used to this idea, but I think it can work. A benefit is that it allows for method chaining: foo.title('new title').color('#f00')
.Another benefit of C is that it becomes trivial to feed a signal output into an input. Maybe like:
self.valid_input.react(self.okButton.enabled)
self.invalid_input.react(signals.not(self.okButton.enabled))
# or feed, connect, ...?
We specify a handful of decorators.
# For input, the function is used to clean/validate the input
@input
def title(v):
return str(v)
# Normal signals have input signals and yield one signal
@signal('signal_a', 'signal_b')
def signal_absum(a, b):
return a + b
# React signals get run on signal changes. They are (usually) end-points
@react('signal_absum')
def show_ab(v):
print('the sum of a and b is ', v)
We could allow this:
class Foo(HasSignals):
title = Input(check_str)
# or even
title = Str()
# and also
title_lower = Signal(lower, ['title'])
... but then we need a metaclass to set the name at the class descriptor signals. If we stick to decorators, its more consistent and we don't need a meta class. Let's go with that for now. if ppl really want it, we can refactor to make use of a meta class.
Use logging, setup a flexx logger instead of using Python's default logger. Also think about logging messages from JS.
def __init__(self):
that = self
x.addEventListener('yy', that._handle_event, 0)
This is ugly. Need to either support a way to make this trivial (like CoffeeScript does) or support bound methods.
We need a few modes of operation:
Widget
, which is decorated. Such "app-widgets" have a launch()
and export()
method.xx.run()
to start serving the runtime. When tornado is running, the app is responsive immediately (no need for xx.run()
).xx.run
or xx.start()
at the beginning to initialize Flexx. Ideally, the output should be such that the widgets remain visible when the notebook is exported (and have JS callbacks working too!).In Qt:
class Main(QtGui.QWidget):
....
app = QtGui.QApplication([])
m = Main()
m.show()
app.exec_()
In Tk:
class Main(Frame):
...
m = Main()
m.mainloop()
In Vispy:
class Main(app.Canvas):
...
c = Main()
app.run()
In Kivi:
class Main(App):
...
m = Main()
m.run()
I tried to run the example code that appears on Fluxx's Github page. I put the code that appears there into the file test1.py:
(py34)Gary-Robinsons-Retina-Macbook-Pro:flexx garyrob$ python test1.py
Serving apps at http://localhost:49270/
Traceback (most recent call last):
File "test1.py", line 17, in <module>
main = app.launch(Example)
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/app/proxy.py", line 387, in launch
proxy = Proxy(cls.__name__, runtime, **runtime_kwargs)
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/app/proxy.py", line 451, in __init__
self._launch_runtime(runtime, **runtime_kwargs)
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/app/proxy.py", line 500, in _launch_runtime
runtime=runtime, **runtime_kwargs)
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/app/proxy.py", line 384, in launch
return webruntime.launch(cls, runtime, **runtime_kwargs)
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/webruntime/__init__.py", line 111, in launch
rt = Runtime(**kwargs)
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/webruntime/common.py", line 91, in __init__
BaseRuntime.__init__(self, **kwargs)
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/webruntime/common.py", line 30, in __init__
self._launch()
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/webruntime/xul.py", line 274, in _launch
exe = self._get_app_exe(xul_exe, app_path)
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/webruntime/xul.py", line 455, in _get_app_exe
self._osx_create_app(op.realpath(xul_exe), exe, title)
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/webruntime/xul.py", line 519, in _osx_create_app
icon = Icon(self._kwargs['icon']) # accepts ico/png/bmp
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/util/icon.py", line 269, in __init__
self.read(filename)
File "/Users/garyrob/anaconda/envs/py34/lib/python3.4/site-packages/flexx/util/icon.py", line 294, in read
raise ValueError('Icon.read() needs a file name')
ValueError: Icon.read() needs a file name
on today trunk, trying find_prime.py
gives this to me:
Traceback (most recent call last):
File "D:/WinPythonQt5/basedir34/build/winpython-3.4.3.amd64/notebooks/find_prime.py", line 60, in <module>
finder = app.launch(PrimeFinder, 'nodejs') # can also use Firefox or Chrome
File "D:\WinPythonQt5\basedir34\build\winpython-3.4.3.amd64\python-3.4.3.amd64\lib\site-packages\flexx\app\funcs.py", line 185, in launch
session = manager.create_session(cls.__name__)
File "D:\WinPythonQt5\basedir34\build\winpython-3.4.3.amd64\python-3.4.3.amd64\lib\site-packages\flexx\app\session.py", line 85, in create_session
app = cls(session=session, container='body')
File "D:\WinPythonQt5\basedir34\build\winpython-3.4.3.amd64\python-3.4.3.amd64\lib\site-packages\flexx\app\model.py", line 244, in __init__
react.HasSignals.__init__(self, **kwargs)
File "D:\WinPythonQt5\basedir34\build\winpython-3.4.3.amd64\python-3.4.3.amd64\lib\site-packages\flexx\react\hassignals.py", line 87, in __init__
raise ValueError('Object does not have a signal %r' % name)
ValueError: Object does not have a signal 'container'
>>>
To avoid this: twosigma/beakerx#2651
Handled in Bokeh with this: bokeh/bokeh#2958
do we have any screenshot or demo?
This is a meta-issue to list the tasks necessary to make Flexx actually work. The plan is to first stick to a very basic but working version, get testing up and running so that it keeps working, and then extend from there.
Functionality required:
Next steps (these points should probably become standalone issues at some point):
Hi,
I tried testing the example from the readme in a (fresh) virtualenv:
pyvenv flex.test
./flex.test/bin/pip install ./flexx.git # Same result if pulling from pypy with "pip install flexx"
cat <<eof > ex.py
#code from readme omitted
eof
./flex.test/bin/python ./ex.py
Traceback (most recent call last):
File "ex.py", line 1, in <module>
from flexx import app, ui, react
File ".../flex.test/lib/python3.4/site-packages/flexx/app/__init__.py", line 61, in <module>
from .proxy import run, start, stop, init_notebook, call_later
File ".../flex.test/lib/python3.4/site-packages/flexx/app/proxy.py", line 10, in <module>
import tornado.ioloop
ImportError: No module named 'tornado'
Added tornado to install_requires
(I use mercurial hg-git):
$ hg diff -c -1
diff -r d14c42b51483 -r 55b0b4821a5c setup.py
--- a/setup.py Sat Sep 05 13:57:35 2015 +0200
+++ b/setup.py Sun Sep 06 13:33:49 2015 +0200
@@ -63,7 +63,7 @@
long_description=__doc__,
platforms='any',
provides=[name],
- install_requires=[],
+ install_requires=['tornado'],
packages=package_tree(name),
package_dir={name: name},
package_data={},
Then virtualenv/pip sets things up correctly, and everything works. Does seem to be awfully few install_requires... Is this a TODO-item?
I initially thought that layout being widgets made things simpler, and it also felt natural because layout are html elements too. However, it makes things less flexible. As Chris put it:
An *extremely* simple case is toggling the layout based on the width
of the parent. This can be changing the orientation of a box layout
or switching from a wrapping flow layout to a vbox layout or
something else.
A more complicated case arises when you build an app which hosts
user-defined content. In these cases you'll typically provide a
widget to user code to use as a host for the user content (which
you know nothing about). If layouts are separate from widgets, you
can just provide an empty widget and the user can assign whatever
layout they please. If not, you have to just choose a host widget
like a VBox, and if that's not what the user wants, they have to
add another level of nesting to achieve their desired layout.
Also interesting: in both Qt and wx, a splitter is a widget, but hbox is a layout. In Qt there is the QStackedLayout, but also the QStackedWidget as a convenience.
Disadvantages of Layouts being widgets:
self._some_widget.parent
will typically not refer to self, but to a layout. To get to self
, you may need to .parent
several times. This is not a performance thing, because regardless of what we choose, the nesting is this deep in the DOM. It's about how the gui hierarchy feels to the user.Disadvantages of Layouts being separate:
someWidget.parent = myWidget.hbox
.Meta issue to collect tasks:
Saw this in a Boxlayout in a Boxlayout with a Widget in between. And also with nexted vboxes with an hbox in between.
from flexx import app, ui
class TestApp2(ui.Widget):
def init(self):
with ui.VBox(flex=1):
ui.Widget(style='background:#f00; min-height:100px;')
TestSubApp2(flex=1)
ui.Widget(style='background:#f00; min-height:100px;')
class TestSubApp2(ui.Widget):
def init(self):
with ui.VBox(flex=1):
ui.Widget(flex=1, style='background:#0f0; min-height:100px;')
ui.Widget(flex=2, style='background:#00f; min-height:100px;')
m = app.launch(TestApp2, 'chrome')
The VBox inside the sub-app does not take up all available space for some reason. Also not if its an hbox.
Currently, Flexx allows writing widget hierarchy like this:
with SomeLayout():
with SubLayout() as layout:
b1 = Button()
b2 = SomeWidget()
b3 = ProgressBar()
... etc.
I like how it is a declarative style, which shows the structure of the app. However, not everyone might like it as much. Some feedback should be collected.
Another approach could be:
b1, b2, b3 = ...
SomeLayout(SubLayout(b1, b2), b3)
If we change layouts to not be widgets, that would have implications on this topic (#9)
Making an issue so that I wont forget. Session id's are now set using the id()
of the session object (i.e. its position in memory). This might be a secutity hazard. Instead the id should be a randomly generated string.
Essential:
Paired
/Mirrored
?Nice:
flexx.webruntime
flexx.react
flexx.pyscript
.git/config
and do further dev using PR'sThis issue describes a new event system to replace flexx.react
. Discussions welcome.
The event system for Flexx should, like the rest of Flexx, be simple and intuitive to use. The current system borrowed some ideas from reactive programming to achieve this. I was initially enthousiastic about RP, but in retrospect I don't think its the right model.
The system in flexx.react
was a fun experiment, and it certainly has some nice features, but it also has some flaws:
mouse_down
state to False)The good features can be summarized as:
'children.*.size'
).I am planning/proposing a new event system that is somewhat more conventional, in that it uses events, but has the nice features of the current system.
What this new system will have (that the current system has not):
Events can only apply to HasEvents
objects (you cannot create events on their own, as you could with signals). You can emit an event using x.emit(name, **values)
. This causes an event object to be created, which is basically a dictionary from values
with some extra info, like owner
.
Edit: I think it makes sense to allow emitting events doing x.event_name(ob)
, which will use ob to produce and emit an event object.
Event objects are simply dicts with some fields. For property-change-events, the fields will be 'value', 'previous_value', 'time', 'previous_time', 'owner'. I think it would be useful to create a subclass to allow easier accessing using ev.value
, but otherwise they're just dicts.
You can connect to an event using:
@connect('foo')
def on_foo(*events):
...
@connect('foo', 'bar')
def update(*events):
...
The decorator is basically the same as it is now, but the function signature now accepts a series of events objects. Even for on_foo()
, the function can be called with multiple 'foo' events, if multiple events where generated during one event loop iteration. Event handlers are free to process all events or only the last one (as update()
will likely do). The decorator turns the function into a callable object (maybe even the original function?), so that you can manually call update()
, which causes events
to be empty.
A decorator @prop
replaces the @input
and can be used to create properties. When a property is changed, an event with the same name is emitted, which contains information about the new value, old value, and timings.
Similarly, there will be a @readprop
(or different name?) decorator for readonly properties (much like the current @source
.
class Foo(HasEvents):
@prop
def name(s='John'):
return str(s).capitalize()
foo = Foo()
@connect('foo.name')
def on_name_change(*events):
print('name %r changed to %r' % (events[-1].value, events[0].previous_value)
foo.name = 'X'
foo.name = 'jane'
# in the next event loop, we will see one message saying "name 'John' changed to 'Jane'".
Event can be defined using
class Foo(HasEvents):
# Short
my_event = Event('x', 'y', # x and y are names that the event object will have
docs='docs on this event')
# I also like this, its 2 lines more, but it allows more flexibility, it allows
# emitting events using `foo.my_event(ob)`, and I prefer writing docstrings this way.
@event
def my_event(ob):
""" docs on this event """
return Event(x=ob.x, y=ob.y) # create Event object based on input passed to `emit()`.
One central concept of RP is that you have streams of signals, where new signals are created from a combination of signals etc. A model like this is still possible, by emitting new events from inside an event handler. We can consider using yield
to generate new events.
Another concept of RP is caching of signal values, which can help make apps that have a long-running operation to run efficiently. I think that it will take little extra effor to create a proxy event to implement this in the new system.
Because multiple events can be handled by a single function, handlers are not called in the order in which they were connected. The order should be deterministic, and I think it makes sense to use the event handler name for this. Event order can be influenced by chosing the handler name, and by a keyword argument to the decorator, e.g. @connect('foo', 'bar', key='__need this first')
. A handler can not prevent the event being passed to other handlers.
The system itself does not implement any form of event propagation, though systems using it can do so. Here's an (overly simplified) example:
class RootNode(Node):
@connect('somewhere.mouse_down')
def _on_mouse_event(self, ev):
ev.handled = False
for node in reversed(children):
node.mouse_event(ev)
if ev.handled:
break
class NodeThatReactsToLMB(Node):
def mouse_event(self, ev):
if ev.button == 1:
...
ev.handled = True
class NodeThatReactsToRMB(Node):
def mouse_event(self, ev):
if ev.button == 2:
...
ev.handled = True
Suggestions and discussion welcome!
Via six.py or python-future.org
I'm a bit tired of making stuff work on both Python2 and Python 3. I just want to write isinstance(c, str)
. But maybe to get Flexx out there and usable from existing projects, I'd have to give in. We'll see.
PyScript support is the trickiest bit, I suppose, because the ast parser behaves slightly different. But the ast parse of pypy is different too, and I very much like to support that. Having a pure Python ast parser would be even more awesome, see #19.
We need an event system and I think it makes sense to make it symmetric as we do with properties: the PyScript API is the same as the Python API.
In any case, we need a way for methods to be event handlers, and have the correct this
. We can do this with an API like:
xxx(..., my_function)
xxx(..., (my_object, 'my_method'))
button.connect_event('click', my_handler)
button.disconnect_event('click', my_handler)
button.emit_event('click', event)
@button.connect_event('click')
def my_handler(event):
...
Cannot use autocompletion, so ppl need to read the docs to know what events are available. But I think its Pythonic. It also feels simple and compact.
button.events.click.connect(my_handler)
button.events.click.disconnect(my_handler)
button.events.click(event) # vispy-style-emitting, but we cannot do this in JS
button.events.click.emit(event) # explicit
@button.events.click.connect
def my_handler(event):
...
A bit verbose, but autocomp is nice to have.
See #15
Also, the event object, we can start with following the JS API. Although we cannot really use native events, because these are for DOM objects. Maybe for clarity also use "owner" instead of "target", etc.
Use cases:
screen
.flexx serve foo.py
will serve all widgets defined in foo.py
).Right now, for some stuff the Python side sends JS over that is eval'ed at the client. I'd like to move to a more formal protocol, and have an explicit entry point for this, to allow using the JS side of Flexx from other systems. In other words, all JS widgets (as written in PyScript) can be used using a completely independent Python library. Or a Julia library, or a JS library...
One use-case I have in mind that if there were a visualization library based on Flexx, it could be compatible with a standardized visualization protocol.
Also, maybe the protocol should be binary, to send data more efficiently, e.g. for visualization. A downside of that is that exported apps would need base64 encoding, or can we put the list of commands in an external (binary) resource?
When trying to use the Chrome runtime on Linux I was getting:
RuntimeError('Chrome or Chromium browser was not detected.')
chromeapp.py is looking for Chrome and Chromium in /usr/lib for some reason:
elif sys.platform.startswith('linux'):
paths.append('/usr/lib/google-chrome/google-chrome')
I don't know of any distros that will be keeping the browser binaries in /usr/lib. Furthermore, the Chrome binary filename should also include the channel. That is: google-chrome-stable, google-chrome-beta, google-chrome-dev.
I fixed the path in chromeapp.py and it's working great.
Changing the above code to:
elif sys.platform.startswith('linux'):
paths.append('/usr/bin/google-chrome-stable')
paths.append('/usr/bin/google-chrome-beta')
paths.append('/usr/bin/google-chrome-dev')
...should support the vast majority of modern distros and all of the Chrome release channels one may have installed.
The same fix should be applied to the Chromium detector function with appropriate file names.
Some projects currently going on (like Jupyter widgets, IBM's work in the notebook, Bokeh apps), target multiple kernel/server languages. Flexx is rather bound to Python, though in principal it should be possible to target languages as well, if we formalize a good client-server communication protocol. Collecting thoughts on this here.
It might be possible to auto-generate e.g. Julia code from the Python implementation. The JS code is already there, though users must be able to write client code as well.
Any target language would need:
Hi,
Looks like a great library and trying to feel out the python space for doing this stuff. I'm pretty new to python (and programming) and brand new to web programming so please excuse the following the noob questions as I had already persued the docs.
Thanks!
Like running flexx serve
, and upon saving the file that defines your app, it gets automatically reloaded in the browser, preferably with state (i.e. what tab is open) preserved.
make the temperature example works with PyQt5 web engine
There are two common problems with PyScript:
flexx.pyscript
, but of course there is plenty of other stuff in JS.Math.X
instead of math.x
, etc.Proposal: Allow a stub from flexx.pyscript import X
, and inside pyscript allow writing X.Math.pi
X.undefined
, X.window
, etc. The transpiler will simply remove X.
wherever it is used.
For the name, it should be short but unique enough. Maybe JS
, js
, root
, jsroot
, __root__
...
If PyScript can compile itself, we can generate a JS implementation of the PyScript transpiler, which means we can allow people to write PyScript directly in HTML docs, support eval()
, and have a PyScript terminal. Sweeeet ...
To get there:
This functionality is not really necessary from the point of view of flexx.ui
, but it would open a lot of new possibilities, and brings PyScript into the same ballpark as Brython and Skulpt.
Now:
@react.input
def foo(value=2):
return float(value)
Maybe:
@react.input
def foo(value:2):
return float(value)
... which would enable getting the default value without executing the function.
or:
@react.input
def foo(value:float=2):
return float(value)
See https://github.com/pybee/batavia
This is very slow, but maybe not if the VM runs on asm.js. It would solve the Achilles heel of PyScript (it's not actual Python). However, interacting with other code becomes harder (but maybe this is not such a problem for Flexx?)
When using Flexx with Python 3.5:
$ python ../signage/demo.py
Traceback (most recent call last):
File "../signage/demo.py", line 1, in <module>
from flexx import app, ui, react
File "/home/chris/signage35/lib/python3.5/site-packages/flexx/app/__init__.py", line 61, in <module>
from .proxy import run, start, stop, init_notebook, call_later
File "/home/chris/signage35/lib/python3.5/site-packages/flexx/app/proxy.py", line 17, in <module>
from .clientcode import clientCode, Exporter # global client code
File "/home/chris/signage35/lib/python3.5/site-packages/flexx/app/clientcode.py", line 48, in <module>
@py2js
File "/home/chris/signage35/lib/python3.5/site-packages/flexx/pyscript/functions.py", line 73, in py2js
p = Parser(pycode, **parser_options)
File "/home/chris/signage35/lib/python3.5/site-packages/flexx/pyscript/parser0.py", line 190, in __init__
self._parts = self.parse(self._root)
File "/home/chris/signage35/lib/python3.5/site-packages/flexx/pyscript/parser0.py", line 340, in parse
res = parse_func(node)
File "/home/chris/signage35/lib/python3.5/site-packages/flexx/pyscript/parser1.py", line 553, in parse_Module
code += self.parse(child)
File "/home/chris/signage35/lib/python3.5/site-packages/flexx/pyscript/parser0.py", line 340, in parse
res = parse_func(node)
File "/home/chris/signage35/lib/python3.5/site-packages/flexx/pyscript/parser2.py", line 770, in parse_ClassDef
if node.keywords or node.starargs or node.kwargs:
AttributeError: 'ClassDef' object has no attribute 'starargs'
See this issue for details on the backwards-compatibility breakage in Python 3.5 with an attached patch they used to fix it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.