pycqa / flake8-import-order Goto Github PK
View Code? Open in Web Editor NEWFlake8 plugin that checks import order against various Python Style Guides
License: GNU Lesser General Public License v3.0
Flake8 plugin that checks import order against various Python Style Guides
License: GNU Lesser General Public License v3.0
from cryptography.x509.oid import (
_OID_NAMES, OID_AUTHORITY_INFORMATION_ACCESS
OID_AUTHORITY_KEY_IDENTIFIER
Gives "Imported names are in the wrong order. Should be _OID_NAMES, OID_AUTHORITY_INFORMATION_ACCESS, OID_AUTHORITY_KEY_IDENTIFIER".
Changing the import to
from cryptography.x509.oid import (
OID_AUTHORITY_INFORMATION_ACCESS
OID_AUTHORITY_KEY_IDENTIFIER, _OID_NAMES
makes it happy.
There appears to be a similar bug with the output msg and its expected ordering related to capitalization as well, although I don't have an example handy right now. This is with flake8-import-order 0.6.1
The typing
module that is part of the standard library as of Python 3.5 is not recognized as being part of the standard library: flake8-import-order is indicating that it belongs to the 3rd party module groups, under google import styling.
pip install --no-use-wheel flake8-import-order
This requires some cleanup of ImportOrderChecker and ImportVisitor first.
In particular there needs to be a clearer separation between getting the import data out of the AST and generating the sort keys that are used to check the ordering. We can then use an RawChecker in PyLint to extract the imports and run the check. This is currently a little complicated due to differences in stdlib ast and astdroid.
I am using Google style imports:
from django.contrib.auth import models as auth
from django.contrib.auth import hashers
Your linter complains about this and says I should swap the order around, but I am using another tool isort to do the sorting, so obviously one way or the other is the correct way, I am not sure which way it is?
i.e. is your linter correct to complain and isort has sorted incorrectly, or is isort correct in this scenario and your linter has picked up a false positive?
Presently it's pretty fragile to list every application-local import name for --application-import-names. Is it possible to check for the presence of the module file in the directory to figure it out?
Example:
Imported names are in the wrong order. Should be RequestContext, get_object_or_404, render, render_to_response
It looks like RequestContext should be in the first position because it is upper case. Am I right?
If yes I can update cryptography example and add a line considering case sensitive imports.
Thanks! (sorry for using issues to make a question)
https://github.com/klen/pylama
For python-mode integration.
As far as I know, this should fail because the imported names aren't sorted alphabetically, but for me it doesn't show any warnings
from sqlalchemy import Integer, MetaData, Column
Integer, MetaData, Column,
I have a file with the following group of imports:
import datetime
import dateutil.parser
import logging
datetime
dateutil.parser
logging
Import order looks right, but flake8 complains about it:
$ flake8 foo.py
foo.py:3:1: I100 Import statements are in the wrong order.import logging should be before import dateutil.parser
Rearranging imports in the following order satisfies flake8:
import datetime
import logging
import dateutil.parser
Is this intended by design? I couldn't find the precise definition of smarkets import style, hence can't tell where is the problem.
The Google style guide states "imports should be sorted lexicographically, ignoring case, according to each module's full package path". This checker sorts seems to sort all 'import foo' statements before all 'from foo import bar' statements, based on this test case. Unfortunately, the Google style guide is missing an example that would make this more obvious, but the wording of the rule makes this quite clear.
In the test case, the first group should be:
import ast # sorted as ast
from functools import * # sorted as functools.*
import os # sorted as os
from os import path # sorted as os.path
import sys # sorted as sys
since functools.*
sorts between ast
and os
.
Imports statements are in the wrong order. from api.modules should be before from api.modules
I got this error because of multiple from api.modules import x, y
import statements. It seems to not consider multiple lines from the same import.
After updating to 2014-10-29 version I started getting lots of:
I201 Missing newline before sections or imports.
For absolute imports followed by relative imports:
from myproject.app.tests import UserFactory
from .tests import SomeClass
I have these settings defined in tox.ini:
import-order-style=google
application-import-names=myproject,myproject2
Anyone else getting changed behavior with the 2014-10-29 release?
A change in the 0.9 release broke the Google order style, at least for I100
. It looks like it is not ignoring the case of letters anymore.
According to the Google Python Style Guide
Within each grouping, imports should be sorted lexicographically, ignoring case, according to each module's full package path.
Here is an example that worked in 0.8, but is flagging I100
in 0.9:
import os
import StringIO
import sys
This (incorrect) example passes in 0.9:
import StringIO
import os
import sys
posixpath is not considered a standard library module
Please.
flake8: access.py:5:1: I101 Imported names are in the wrong order. Should be connection, IntegrityError, transaction
line 5 of access.py: from django.db import connection, IntegrityError, transaction
Resolved with:
from django.db import IntegrityError
from django.db import connection, transaction
the correctness of an import is checked even if the line is commented with # noqa. it should be skipped.
It's convenient that this plugin suggests the correct import order, but it lowercases all of the modules. It would be nice if it didn't do that so I could just copy/paste the correct order.
My incorrect code:
from libnl.linux_private.netlink import NETLINK_ROUTE, NLMSG_LENGTH, NLM_F_DUMP, NLM_F_REQUEST
from libnl.linux_private.rtnetlink import RTA_DATA, RTA_NEXT, RTA_OK, RTM_GETLINK, ifinfomsg, rtgenmsg
Suggested:
./example_list_network_interfaces.py:45:1: I101 Imported names are in the wrong order. Should be netlink_route, nlm_f_dump, nlm_f_request, nlmsg_length
./example_list_network_interfaces.py:46:1: I101 Imported names are in the wrong order. Should be ifinfomsg, rta_data, rta_next, rta_ok, rtgenmsg, rtm_getlink
not sure if a dup of #44 but for completeness:
pelican/tests/test_settings.py:11:1: I101 Imported names are in the wrong order. Should be configure_settings, DEFAULT_CONFIG, DEFAULT_THEME, read_settings
but
11 from pelican.settings import (configure_settings, DEFAULT_CONFIG,
12 DEFAULT_THEME, read_settings)
In pep8 mode code files containing standard library imports after third party ones cause a TypeError in ImportOrderChecker.check_order.build_str
.
Minimal example:
test.py
:
import thirdparty
import sys
~ # pip install flake8 flake8-import-order
[...]
Successfully installed flake8-2.6.2 flake8-import-order-0.8 mccabe-0.5.0 pep8-1.7.0 pycodestyle-2.0.0 pyflakes-1.2.3
~ # flake8 --import-order-style=pep8 test.py
Traceback (most recent call last):
File "/Users/ulo/Envs/tmp-686c3c2aab00eaf/bin/flake8", line 11, in <module>
sys.exit(main())
File "/Users/ulo/Envs/tmp-686c3c2aab00eaf/lib/python3.5/site-packages/flake8/main.py", line 36, in main
report = flake8_style.check_files()
File "/Users/ulo/Envs/tmp-686c3c2aab00eaf/lib/python3.5/site-packages/flake8/engine.py", line 181, in check_files
return self._retry_serial(self._styleguide.check_files, paths=paths)
File "/Users/ulo/Envs/tmp-686c3c2aab00eaf/lib/python3.5/site-packages/flake8/engine.py", line 172, in _retry_serial
return func(*args, **kwargs)
File "/Users/ulo/Envs/tmp-686c3c2aab00eaf/lib/python3.5/site-packages/pycodestyle.py", line 1877, in check_files
runner(path)
File "/Users/ulo/Envs/tmp-686c3c2aab00eaf/lib/python3.5/site-packages/flake8/engine.py", line 126, in input_file
return fchecker.check_all(expected=expected, line_offset=line_offset)
File "/Users/ulo/Envs/tmp-686c3c2aab00eaf/lib/python3.5/site-packages/pycodestyle.py", line 1608, in check_all
self.check_ast()
File "/Users/ulo/Envs/tmp-686c3c2aab00eaf/lib/python3.5/site-packages/pycodestyle.py", line 1555, in check_ast
for lineno, offset, text, check in checker.run():
File "/Users/ulo/Envs/tmp-686c3c2aab00eaf/lib/python3.5/site-packages/flake8_import_order/flake8_linter.py", line 52, in run
for error in self.check_order():
File "/Users/ulo/Envs/tmp-686c3c2aab00eaf/lib/python3.5/site-packages/flake8_import_order/__init__.py", line 289, in check_order
first_str = build_str(k)
File "/Users/ulo/Envs/tmp-686c3c2aab00eaf/lib/python3.5/site-packages/flake8_import_order/__init__.py", line 283, in build_str
if level >= 0:
TypeError: unorderable types: NoneType() >= int()
I have the following imports at the top of one of my files:
from collections import OrderedDict, namedtuple
import datetime
import coffin.template.loader
from django.core import validators
from django.utils.functional import SimpleLazyObject, cached_property
import lib.forms
import lib.models
However, when I run flake8
on it, I get the following warning:
my_file.py:4:1: I100 Imports are in the wrong order
import coffin.template.loader
^
This looks lexigraphically sorted to me, and coffin
is certainly in my site-packages.
Also, I would expect to see a warning for line 6, since cached_property
should sort before SimpleLazyObject
according to the Google Styleguide ("imports should be sorted lexicographically, ignoring case").
smarkets
is not listed with --help
is supplied:
--import-order-style=IMPORT_ORDER_STYLE
Style to follow. Available: cryptography, google
When linting a file from stdin, this plugin raises an error.
$ cat conftest.py | flake8 -
Traceback (most recent call last):
File "/tmp/venv/bin/flake8", line 11, in <module>
sys.exit(main())
File "/tmp/venv/lib/python3.5/site-packages/flake8/main/cli.py", line 16, in main
app.run(argv)
File "/tmp/venv/lib/python3.5/site-packages/flake8/main/application.py", line 316, in run
self._run(argv)
File "/tmp/venv/lib/python3.5/site-packages/flake8/main/application.py", line 300, in _run
self.run_checks()
File "/tmp/venv/lib/python3.5/site-packages/flake8/main/application.py", line 238, in run_checks
self.file_checker_manager.run()
File "/tmp/venv/lib/python3.5/site-packages/flake8/checker.py", line 346, in run
self.run_serial()
File "/tmp/venv/lib/python3.5/site-packages/flake8/checker.py", line 330, in run_serial
checker.run_checks(self.results_queue, self.statistics_queue)
File "/tmp/venv/lib/python3.5/site-packages/flake8/checker.py", line 564, in run_checks
self.run_ast_checks()
File "/tmp/venv/lib/python3.5/site-packages/flake8/checker.py", line 475, in run_ast_checks
for (line_number, offset, text, check) in runner:
File "/tmp/venv/lib/python3.5/site-packages/flake8_import_order/flake8_linter.py", line 66, in run
for error in self.check_order():
File "/tmp/venv/lib/python3.5/site-packages/flake8_import_order/checker.py", line 46, in check_order
if not pycodestyle.noqa(self.lines[import_.lineno - 1]):
IndexError: list index out of range
This does work when just linting a file instead.
$ flake8 conftest.py
$
I've installed the following packages in my environment (simply a virtualenv using the latest flake8
and flake8-import-order
).
$ pip list
flake8 (3.0.2)
flake8-import-order (0.9.1)
mccabe (0.5.0)
pip (8.1.2)
pycodestyle (2.0.0)
pyflakes (1.2.3)
setuptools (25.1.0)
wheel (0.29.0)
This bug does not yet exist when using the following requirements:
flake8 ~= 2.5.5
flake8-import-order ~= 0.8.0
I didn't try this using flake8 ~= 2.6.0
, because this was causing errors related to other plugins.
There seems to be a regression between 0.6.1 and 0.9.2. The following imports are no longer considered in wrong order (H, then C, the P). flake8-import-order == 0.6.1 reported this.
from custodia.plugin import HTTPConsumer, HTTPError
from custodia.plugin import CSStoreError, CSStoreExists, PluginOption
macurl2path and nturl2path are not considered standard library modules. please add them. tnx
First of all first for this project :).
xml.etree is missing from stdlib_list.py and wrongly reports it as local module.
I.e.:
from xml.etree import ElementTree as ET
Also:
Hi would it be possible to share the same error code namespace with your plugin in flake8-future-import? At the moment I'm using FI??
but there is a request (xZise/flake8-future-import#5) to use LDDD
(L = letter, D = digit) but I don't know what letter to choose basically. F
(for future imports) and I
(for imports) are both taken, and I could of course use other letters but they wouldn't have any meaning.
So my idea was if we could agree that I maybe use I900
to I999
, so basically replacing FI
with I9
. Especially as both plugins have a similar scope in checking the imports.
(cryptography) ~/p/cryptography (master) $ flake8
Traceback (most recent call last):
File "/Users/alex_gaynor/.virtualenvs/cryptography/bin/flake8", line 11, in <module>
sys.exit(main())
File "/Users/alex_gaynor/.virtualenvs/cryptography/site-packages/flake8/main/cli.py", line 16, in main
app.run(argv)
File "/Users/alex_gaynor/.virtualenvs/cryptography/site-packages/flake8/main/application.py", line 299, in run
self._run(argv)
File "/Users/alex_gaynor/.virtualenvs/cryptography/site-packages/flake8/main/application.py", line 285, in _run
self.initialize(argv)
File "/Users/alex_gaynor/.virtualenvs/cryptography/site-packages/flake8/main/application.py", line 276, in initialize
self.register_plugin_options()
File "/Users/alex_gaynor/.virtualenvs/cryptography/site-packages/flake8/main/application.py", line 150, in register_plugin_options
self.check_plugins.register_options(self.option_manager)
File "/Users/alex_gaynor/.virtualenvs/cryptography/site-packages/flake8/plugins/manager.py", line 451, in register_options
list(self.manager.map(register_and_enable))
File "/Users/alex_gaynor/.virtualenvs/cryptography/site-packages/flake8/plugins/manager.py", line 261, in map
yield func(self.plugins[name], *args, **kwargs)
File "/Users/alex_gaynor/.virtualenvs/cryptography/site-packages/flake8/plugins/manager.py", line 447, in register_and_enable
call_register_options(plugin)
File "/Users/alex_gaynor/.virtualenvs/cryptography/site-packages/flake8/plugins/manager.py", line 357, in generated_function
return method(optmanager, *args, **kwargs)
File "/Users/alex_gaynor/.virtualenvs/cryptography/site-packages/flake8/plugins/manager.py", line 207, in register_options
add_options(optmanager)
File "/Users/alex_gaynor/.virtualenvs/cryptography/site-packages/flake8_import_order/flake8_linter.py", line 32, in add_options
parser.config_options.append("application-import-names")
AttributeError: 'OptionManager' object has no attribute 'config_options'
SublimeLinter runs flake8 against stdin, so installing flake8-import-linter breaks SublimeLinter.
To reproduce:
echo | flake8 -
Exception:
Traceback (most recent call last):
File "/Users/dstensland/.virtualenvs/foobar/bin/flake8", line 9, in <module>
load_entry_point('flake8==2.1.0', 'console_scripts', 'flake8')()
File "/Users/dstensland/.virtualenvs/foobar/lib/python2.7/site-packages/flake8/main.py", line 32, in main
report = flake8_style.check_files()
File "/Users/dstensland/.virtualenvs/foobar/lib/python2.7/site-packages/pep8.py", line 1672, in check_files
runner(path)
File "/Users/dstensland/.virtualenvs/foobar/lib/python2.7/site-packages/flake8/engine.py", line 73, in input_file
return fchecker.check_all(expected=expected, line_offset=line_offset)
File "/Users/dstensland/.virtualenvs/foobar/lib/python2.7/site-packages/pep8.py", line 1410, in check_all
self.check_ast()
File "/Users/dstensland/.virtualenvs/foobar/lib/python2.7/site-packages/pep8.py", line 1359, in check_ast
for lineno, offset, text, check in checker.run():
File "/Users/dstensland/.virtualenvs/foobar/lib/python2.7/site-packages/flake8_import_order/flake8_linter.py", line 38, in run
for error in self.check_order():
File "/Users/dstensland/.virtualenvs/foobar/lib/python2.7/site-packages/flake8_import_order/__init__.py", line 152, in check_order
self.tree = ast.parse(open(self.filename).read())
IOError: [Errno 2] No such file or directory: 'stdin'
(tempenv-7746105805205) ~/p/h/usds-buildbot $ flake8 buildbot.py test_buildbot.py
test_buildbot.py:4:1: I101 Imported names are in the wrong order. Should be Contact, parse_project, RawSegment, split_document, split_section
(tempenv-7746105805205) ~/p/h/usds-buildbot $ head test_buildbot.py
import datetime
import textwrap
from buildbot import (
Contact, parse_project, RawSegment, split_document, split_section
)
TEST_DOCUMENT = """
# Projects underway with a fully staffed team
They should be more helpful and try and get you to put stuff in the right place.
In 0.5 this worked fine:
import atexit
import codecs
import os
import re
import subprocess
import sys
from distutils.spawn import find_executable
import setuptools
from setuptools.command.test import test
But in 0.6 I'm getting:
./setup.py:10:1: I100 Imports statements are in the wrong order. from distutils.spawn should be before from sys
1 I100 Imports statements are in the wrong order. from distutils.spawn should be before from sys
0.6 wants to put "from distutils..." between codecs and os.
The following code:
from __future__ import absolute_import, division, print_function
import binascii
import pretend
import pytest
import six
from cryptography.exceptions import (
AlreadyFinalized, InvalidSignature, _Reasons
)
from cryptography.hazmat.backends.interfaces import CMACBackend
from cryptography.hazmat.primitives.ciphers.algorithms import (
AES, ARC4, TripleDES
)
from cryptography.hazmat.primitives.cmac import CMAC
from ..backends.test_multibackend import DummyCMACBackend
from ...utils import (
load_nist_vectors, load_vectors_from_file, raises_unsupported_algorithm
)
Results in the following warnings:
./tests/hazmat/primitives/test_cmac.py:33:1: I100 Imports statements are in the wrong order. from backends.test_multibackend should be before from cryptography.hazmat.primitives.cmac
I'm not able to find any changelog for the new 0.6 release of flake8-import-order
and I honestly don't know if I safe to update it in my projects from 0.5.3
Can you provide changelog somewhere (in README or CHANGES) to be able track changes between releases?
Here a good writing on why users needs changelogs
Thanks
The license header boilerplate in __about__.py
is Apache Software License 2.0, while it should probably be LGPLv3; __about__.py
itself has __license__ = "LGPLv3"
in the code.
Also, it wouldn't hurt to add license headers to all source files.
This is a rather minor issue but when I was reading through the README I noticed that you mention the I103
warning but there seems to be no such warning.
for 0.7 there is no tar-ball on pypi, which are used for distributions to package the module. Would be great, if you could provide one again.
The following code gives a flake8 error, and I don't think it should:
import nacl.c
from nacl import encoding
If it's correct that this is failing, it'd be great if it the error message was a bit more descriptive.
Hi!
I found flake8-import-order
can not work well with some modules which are only built-in in python3 in python2 environment, like concurrent.futures
. For example:
$ cat a.py
import concurrent.futures
import click
$ python --version
Python 2.7.10
$ flake8 a.py
a.py:1:1: F401 'concurrent.futures' imported but unused
a.py:2:1: F401 'click' imported but unused
There is no I100
warning which should show in python2.
Then I modified a.py
:
$ cat a.py
import click
import concurrent.futures
$ flake8 a.py
a.py:1:1: F401 'click' imported but unused
a.py:2:1: F401 'concurrent.futures' imported but unused
a.py:2:1: I100 Import statements are in the wrong order.import concurrent.futures should be before import click
There is an I100
warning which should not show in this import order.
I think it should be more flexible in python2 for these modules like concurrent.futures
.
Thanks for your patience and sorry for my poor English.
Now that there is a pep8
style, I would suggest that it be considered for the default. While I personally use google
and will continue to specify this, I think for the general use case this makes the most sense as the default.
I totally get though that this was made for the cryptography
devs by the cryptography
dev and that is clearly stated in the README
. So this is not a necessary change, but I do think it would be just a little better. This would allow someone to just pip install
it along side other PEP8 extensions (like pep8-naming
) and get an out-of-the-box experience that they might expect.
Again, thanks for the great tool.
I'm running flake8-import-order on Python 3.4:
$ flake8 --version
2.2.2 (pep8: 1.5.7, import-order: 0.4.2, pyflakes: 0.8.1, mccabe: 0.2.1) CPython 3.4.0 on Linux
And it crashes because of a comparison of str and None:
$ flake8
Traceback (most recent call last):
File "/home/jodal/dev/virtualenvs/vega3/bin/flake8", line 11, in <module>
sys.exit(main())
File "/home/jodal/dev/virtualenvs/vega3/lib/python3.4/site-packages/flake8/main.py", line 32, in main
report = flake8_style.check_files()
File "/home/jodal/dev/virtualenvs/vega3/lib/python3.4/site-packages/pep8.py", line 1670, in check_files
self.input_dir(path)
File "/home/jodal/dev/virtualenvs/vega3/lib/python3.4/site-packages/pep8.py", line 1706, in input_dir
runner(os.path.join(root, filename))
File "/home/jodal/dev/virtualenvs/vega3/lib/python3.4/site-packages/flake8/engine.py", line 83, in input_file
return fchecker.check_all(expected=expected, line_offset=line_offset)
File "/home/jodal/dev/virtualenvs/vega3/lib/python3.4/site-packages/pep8.py", line 1412, in check_all
self.check_ast()
File "/home/jodal/dev/virtualenvs/vega3/lib/python3.4/site-packages/pep8.py", line 1359, in check_ast
for lineno, offset, text, check in checker.run():
File "/home/jodal/dev/virtualenvs/vega3/lib/python3.4/site-packages/flake8_import_order/flake8_linter.py", line 49, in run
for error in self.check_order():
File "/home/jodal/dev/virtualenvs/vega3/lib/python3.4/site-packages/flake8_import_order/__init__.py", line 206, in check_order
if n < pn:
TypeError: unorderable types: str() < NoneType()
But it works when running flake8 with Python 2.7 on the same code base:
$ flake8 --version
2.2.2 (pep8: 1.5.7, mccabe: 0.2.1, import-order: 0.4.2, pyflakes: 0.8.1) CPython 2.7.6 on Linux
$ flake8
$ echo $?
0
Hi there, thanks for this fantastic library.
I notice that 0.7 has been released, but the changelog does not say what the changes were. May I ask that it be updated, please?
With version 0.6.1, I get error I101:
from gazpacho.mdp02 import (
broker,
echo,
InvalidCommand,
Majordomo02Broker,
Majordomo02Client,
Majordomo02Worker,
Reconnect,
tunnel,
worker,
)
Here is the error message:
./tests/test_mdp02.py:10:1: I101 Imported names are in the wrong order. Should be broker, echo, InvalidCommand, Majordomo02Broker, Majordomo02Client, Majordomo02Worker, Reconnect, tunnel, worker
I actually copy-pasted the names in the message to make sure they're in the same order as the message says they should be, but I still get the error.
I reorderd them using M-x sort-lines
in Emacs, which gave this result and the error no longer appears:
from gazpacho.mdp02 import (
InvalidCommand,
Majordomo02Broker,
Majordomo02Client,
Majordomo02Worker,
Reconnect,
broker,
echo,
tunnel,
worker,
)
According to issue #40, it seems this is indeed the correct order. However, it's quite annoying that the error message suggests the incorrect order :-)
From the Limitations section of the docs:
The classification of an import as being non-stdlib of some kind depends on that package actually being installed.
But looking at the code in _import_type()
it seems like what really happens is that if the module doesn't match the others, it's considered to be third party. This was confusing at first because based on the documentation I tried installing/uninstalling third party packages to try to fix issues:
else:
# Not future, stdlib or an application import.
# Must be 3rd party.
return IMPORT_3RD_PARTY
Next:
You will want to set the application-import-names option to a comma separated list of names that should be considered local to your application. These will be used to help categorise your import statements into the correct groups.
Also from _import_type()
, it would be helpful to new users to mention that relative imports are always considered local:
if name is None:
# relative import
return IMPORT_APP
...
elif isinstance(node, ast.ImportFrom) and node.level > 0:
return IMPORT_APP_RELATIVE
I realize these are somewhat implementation details, but I think they really help new comers determine why many of the locals are properly recognized, but not others.
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.