pax_global_header00006660000000000000000000000064135743563310014524gustar00rootroot0000000000000052 comment=2921ed0b27da1bb8912a68b534624a7172342729 aiosqlite-0.11.0/000077500000000000000000000000001357435633100135755ustar00rootroot00000000000000aiosqlite-0.11.0/.github/000077500000000000000000000000001357435633100151355ustar00rootroot00000000000000aiosqlite-0.11.0/.github/issue_template.md000066400000000000000000000002171357435633100205020ustar00rootroot00000000000000### Description ### Details * OS: * Python version: * aiosqlite version: * Can you repro on master? * Can you repro in a clean virtualenv? aiosqlite-0.11.0/.github/pull_request_template.md000066400000000000000000000000751357435633100221000ustar00rootroot00000000000000### Description Fixes: # aiosqlite-0.11.0/.github/workflows/000077500000000000000000000000001357435633100171725ustar00rootroot00000000000000aiosqlite-0.11.0/.github/workflows/build.yml000066400000000000000000000015561357435633100210230ustar00rootroot00000000000000name: Build on: push: branches: - master tags: - v* pull_request: jobs: aiosqlite: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: python-version: [3.5, 3.6, 3.7] os: [macOS-latest, ubuntu-latest, windows-latest] steps: - name: Checkout uses: actions/checkout@v1 - name: Set Up Python ${{ matrix.python-version }} uses: actions/setup-python@v1 with: python-version: ${{ matrix.python-version }} - name: Install run: | python -m pip install --upgrade pip make setup pip install -U . - name: Test run: make test - name: Lint run: make lint - name: Coverage run: codecov --token ${{ secrets.CODECOV_TOKEN }} --branch ${{ github.ref }} continue-on-error: true aiosqlite-0.11.0/.gitignore000066400000000000000000000022521357435633100155660ustar00rootroot00000000000000README test.db* # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # dotenv .env # virtualenv .venv venv/ ENV/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ # Editors .vscode/ aiosqlite-0.11.0/.ptrconfig000066400000000000000000000003271357435633100155730ustar00rootroot00000000000000[ptr] atonce = 10 exclude_patterns = build* yocto extra_build_env_prefix = /usr/local pypi_url = https://pypi.org/simple/ venv_pkgs = aiounittest black coverage flake8 mypy pip pylint setuptools aiosqlite-0.11.0/.pylint000066400000000000000000000402101357435633100151120ustar00rootroot00000000000000[MASTER] # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code extension-pkg-whitelist= # Add files or directories to the blacklist. They should be base names, not # paths. ignore=CVS # Add files or directories matching the regex patterns to the blacklist. The # regex matches against base names, not paths. ignore-patterns= # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). #init-hook= # Use multiple processes to speed up Pylint. jobs=1 # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. load-plugins= # Pickle collected data for later comparisons. persistent=yes # Specify a configuration file. #rcfile= # When enabled, pylint would attempt to guess common misconfiguration and emit # user-friendly hints instead of false-positive error messages suggestion-mode=yes # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no [MESSAGES CONTROL] # Only show warnings with the listed confidence levels. Leave empty to show # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED confidence= # Disable the message, report, category or checker with the given id(s). You # can either give multiple identifiers separated by comma (,) or put this # option multiple times (only on the command line, not in the configuration # file where it should appear only once).You can also use "--disable=all" to # disable everything first and then reenable specific checks. For example, if # you want to run only the similarities checker, you can use "--disable=all # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" disable=print-statement, parameter-unpacking, unpacking-in-except, old-raise-syntax, backtick, long-suffix, old-ne-operator, old-octal-literal, import-star-module-level, non-ascii-bytes-literal, raw-checker-failed, bad-inline-option, locally-disabled, locally-enabled, file-ignored, suppressed-message, useless-suppression, deprecated-pragma, apply-builtin, basestring-builtin, buffer-builtin, cmp-builtin, coerce-builtin, execfile-builtin, file-builtin, long-builtin, raw_input-builtin, reduce-builtin, standarderror-builtin, unicode-builtin, xrange-builtin, coerce-method, delslice-method, getslice-method, setslice-method, no-absolute-import, old-division, dict-iter-method, dict-view-method, next-method-called, metaclass-assignment, indexing-exception, raising-string, reload-builtin, oct-method, hex-method, nonzero-method, cmp-method, input-builtin, round-builtin, intern-builtin, unichr-builtin, map-builtin-not-iterating, zip-builtin-not-iterating, range-builtin-not-iterating, filter-builtin-not-iterating, using-cmp-argument, eq-without-hash, div-method, idiv-method, rdiv-method, exception-message-attribute, invalid-str-codec, sys-max-int, bad-python3-import, deprecated-string-function, deprecated-str-translate-call, deprecated-itertools-function, deprecated-types-field, next-method-defined, dict-items-not-iterating, dict-keys-not-iterating, dict-values-not-iterating, bad-continuation, missing-docstring, invalid-name, protected-access, wrong-import-order, broad-except, unexpected-line-ending-format # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option # multiple time (only on the command line, not in the configuration file where # it should appear only once). See also the "--disable" option for examples. enable=c-extension-no-member [REPORTS] # Python expression which should return a note less than 10 (10 is the highest # note). You have access to the variables errors warning, statement which # respectively contain the number of errors / warnings messages and the total # number of statements analyzed. This is used by the global evaluation report # (RP0004). evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) # Template used to display messages. This is a python new-style format string # used to format the message information. See doc for all details #msg-template= # Set the output format. Available formats are text, parseable, colorized, json # and msvs (visual studio).You can also give a reporter class, eg # mypackage.mymodule.MyReporterClass. output-format=text # Tells whether to display a full report or only the messages reports=no # Activate the evaluation score. score=no [REFACTORING] # Maximum number of nested blocks for function / method body max-nested-blocks=5 # Complete name of functions that never returns. When checking for # inconsistent-return-statements if a never returning function is called then # it will be considered as an explicit return statement and no message will be # printed. never-returning-functions=optparse.Values,sys.exit [LOGGING] # Logging modules to check that the string format arguments are in logging # function parameter format logging-modules=logging [SPELLING] # Limits count of emitted suggestions for spelling mistakes max-spelling-suggestions=4 # Spelling dictionary name. Available dictionaries: none. To make it working # install python-enchant package. spelling-dict= # List of comma separated words that should not be checked. spelling-ignore-words= # A path to a file that contains private dictionary; one word per line. spelling-private-dict-file= # Tells whether to store unknown words to indicated private dictionary in # --spelling-private-dict-file option instead of raising a message. spelling-store-unknown-words=no [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. notes=FIXME, XXX, TODO [TYPECHECK] # List of decorators that produce context managers, such as # contextlib.contextmanager. Add to this list to register other decorators that # produce valid context managers. contextmanager-decorators=contextlib.contextmanager # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E1101 when accessed. Python regular # expressions are accepted. generated-members= # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). ignore-mixin-members=yes # This flag controls whether pylint should warn about no-member and similar # checks whenever an opaque object is returned when inferring. The inference # can return multiple potential results while evaluating a Python object, but # some branches might not be evaluated, which results in partial inference. In # that case, it might be useful to still emit no-member and other checks for # the rest of the inferred objects. ignore-on-opaque-inference=yes # List of class names for which member attributes should not be checked (useful # for classes with dynamically set attributes). This supports the use of # qualified names. ignored-classes=optparse.Values,thread._local,_thread._local # List of module names for which member attributes should not be checked # (useful for modules/projects where namespaces are manipulated during runtime # and thus existing member attributes cannot be deduced by static analysis. It # supports qualified module names, as well as Unix pattern matching. ignored-modules= # Show a hint with possible names when a member name was not found. The aspect # of finding the hint is based on edit distance. missing-member-hint=yes # The minimum edit distance a name should have in order to be considered a # similar match for a missing member name. missing-member-hint-distance=1 # The total number of similar names that should be taken in consideration when # showing a hint for a missing member. missing-member-max-choices=1 [VARIABLES] # List of additional names supposed to be defined in builtins. Remember that # you should avoid to define new builtins when possible. additional-builtins= # Tells whether unused global variables should be treated as a violation. allow-global-unused-variables=yes # List of strings which can identify a callback function by name. A callback # name must start or end with one of those strings. callbacks=cb_, _cb # A regular expression matching the name of dummy variables (i.e. expectedly # not used). dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ # Argument names that match this expression will be ignored. Default to name # with leading underscore ignored-argument-names=_.*|^ignored_|^unused_ # Tells whether we should check for unused import in __init__ files. init-import=no # List of qualified module names which can have objects that can redefine # builtins. redefining-builtins-modules=six.moves,past.builtins,future.builtins [FORMAT] # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. expected-line-ending-format=LF # Regexp for a line that is allowed to be longer than the limit. ignore-long-lines=^\s*(# )??$ # Number of spaces of indent required inside a hanging or continued line. indent-after-paren=4 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). indent-string=' ' # Maximum number of characters on a single line. max-line-length=88 # Maximum number of lines in a module max-module-lines=1000 # List of optional constructs for which whitespace checking is disabled. `dict- # separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. # `trailing-comma` allows a space between comma and closing bracket: (a, ). # `empty-line` allows space-only lines. no-space-check=trailing-comma, dict-separator # Allow the body of a class to be on the same line as the declaration if body # contains single statement. single-line-class-stmt=no # Allow the body of an if to be on the same line as the test if there is no # else. single-line-if-stmt=no [SIMILARITIES] # Ignore comments when computing similarities. ignore-comments=yes # Ignore docstrings when computing similarities. ignore-docstrings=yes # Ignore imports when computing similarities. ignore-imports=no # Minimum lines number of a similarity. min-similarity-lines=4 [BASIC] # Naming style matching correct argument names argument-naming-style=snake_case # Regular expression matching correct argument names. Overrides argument- # naming-style #argument-rgx= # Naming style matching correct attribute names attr-naming-style=snake_case # Regular expression matching correct attribute names. Overrides attr-naming- # style #attr-rgx= # Bad variable names which should always be refused, separated by a comma bad-names=foo, bar, baz, toto, tutu, tata # Naming style matching correct class attribute names class-attribute-naming-style=any # Regular expression matching correct class attribute names. Overrides class- # attribute-naming-style #class-attribute-rgx= # Naming style matching correct class names class-naming-style=PascalCase # Regular expression matching correct class names. Overrides class-naming-style #class-rgx= # Naming style matching correct constant names const-naming-style=UPPER_CASE # Regular expression matching correct constant names. Overrides const-naming- # style #const-rgx= # Minimum line length for functions/classes that require docstrings, shorter # ones are exempt. docstring-min-length=-1 # Naming style matching correct function names function-naming-style=snake_case # Regular expression matching correct function names. Overrides function- # naming-style #function-rgx= # Good variable names which should always be accepted, separated by a comma good-names=i, j, k, ex, Run, _ # Include a hint for the correct naming format with invalid-name include-naming-hint=no # Naming style matching correct inline iteration names inlinevar-naming-style=any # Regular expression matching correct inline iteration names. Overrides # inlinevar-naming-style #inlinevar-rgx= # Naming style matching correct method names method-naming-style=snake_case # Regular expression matching correct method names. Overrides method-naming- # style #method-rgx= # Naming style matching correct module names module-naming-style=snake_case # Regular expression matching correct module names. Overrides module-naming- # style #module-rgx= # Colon-delimited sets of names that determine each other's naming style when # the name regexes allow several styles. name-group= # Regular expression which should only match function or class names that do # not require a docstring. no-docstring-rgx=^_ # List of decorators that produce properties, such as abc.abstractproperty. Add # to this list to register other decorators that produce valid properties. property-classes=abc.abstractproperty # Naming style matching correct variable names variable-naming-style=snake_case # Regular expression matching correct variable names. Overrides variable- # naming-style #variable-rgx= [IMPORTS] # Allow wildcard imports from modules that define __all__. allow-wildcard-with-all=no # Analyse import fallback blocks. This can be used to support both Python 2 and # 3 compatible code, which means that the block might have code that exists # only in one or another interpreter, leading to false positives when analysed. analyse-fallback-blocks=no # Deprecated modules which should not be used, separated by a comma deprecated-modules=optparse,tkinter.tix # Create a graph of external dependencies in the given file (report RP0402 must # not be disabled) ext-import-graph= # Create a graph of every (i.e. internal and external) dependencies in the # given file (report RP0402 must not be disabled) import-graph= # Create a graph of internal dependencies in the given file (report RP0402 must # not be disabled) int-import-graph= # Force import order to recognize a module as part of the standard # compatibility libraries. known-standard-library= # Force import order to recognize a module as part of a third party library. known-third-party=enchant [CLASSES] # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__, __new__, setUp # List of member names, which should be excluded from the protected access # warning. exclude-protected=_asdict, _fields, _replace, _source, _make # List of valid names for the first argument in a class method. valid-classmethod-first-arg=cls # List of valid names for the first argument in a metaclass class method. valid-metaclass-classmethod-first-arg=mcs [DESIGN] # Maximum number of arguments for function / method max-args=5 # Maximum number of attributes for a class (see R0902). max-attributes=7 # Maximum number of boolean expressions in a if statement max-bool-expr=5 # Maximum number of branch for function / method body max-branches=12 # Maximum number of locals for function / method body max-locals=15 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of public methods for a class (see R0904). max-public-methods=20 # Maximum number of return / yield for function / method body max-returns=6 # Maximum number of statements in function / method body max-statements=50 # Minimum number of public methods for a class (see R0903). min-public-methods=2 [EXCEPTIONS] # Exceptions that will emit a warning when being caught. Defaults to # "Exception" overgeneral-exceptions=Exception aiosqlite-0.11.0/.pyup.yml000066400000000000000000000001141357435633100153670ustar00rootroot00000000000000assignees: jreese label_prs: update schedule: "every two weeks on saturday" aiosqlite-0.11.0/CHANGELOG.md000066400000000000000000000055671357435633100154230ustar00rootroot00000000000000aiosqlite ========= v0.11.0 ------- Feature release - Added support for `set_progress_handler` (#49) - Improved and updated documentation ``` $ git shortlog -s v0.10.0...v0.11.0 9 John Reese 4 Stanislas 2 Vladislav Yarmak 1 pyup-bot 5 tat2grl85 ``` v0.10.0 ------- Feature release v0.10.0: - Support using connections without context managers (#29) - Include test suite in aiosqlite package ``` $ git shortlog -s v0.9.0...v0.10.0 16 John Reese 1 Simon Willison 1 dark0ghost ``` v0.9.0 ------ Feature release v0.9.0: - Support for sqlite extensions - Fixed support for type annotations on early Python 3.5 ``` $ git shortlog -s v0.8.1...v0.9.0 2 Alexander Lyon 3 John Reese ``` v0.8.1 ------ Bug fix release v0.8.1: - Fix connections to byte string db locations (#20) ``` $ git shortlog -s v0.8.0...v0.8.1 1 DevilXD 6 John Reese ``` v0.8.0 ------ Major release v0.8.0: - Use futures instead of polling for connections/cursors. This will significantly reduce time spent blocking the primary event loop, resulting in better performance of asyncio applications using aiosqlite. ``` $ git shortlog -s v0.7.0...v0.8.0 3 John Reese 2 Matthew Schubert ``` v0.7.0 ------ Feature release v0.7.0: - Added macros for combined insert/id and select/fetch - Better perf testing output ``` $ git shortlog -s v0.6.0...v0.7.0 1 Grigi 4 John Reese ``` v0.6.0 ------ Feature release v0.6.0: - Performance improvements for atomic or fast queries - Support passing Path-like objects to aiosqlite.connect - Unit tests now use aiounittest instead of a custom test harness - Limited set of performance tests now available ``` $ git shortlog -s v0.5.0...v0.6.0 1 Grigi 8 John Reese ``` v0.5.0 ------ Feature release v0.5.0: - More aliases from sqlite3, including Row, errors, and register_* - Additional connection properties for row/text factory, total changes - Better readme ``` $ git shortlog -s v0.4.0...v0.5.0 6 John Reese ``` v0.4.0 ------ Feature release v0.4.0: - Enable using a custom asyncio event loop - Increase performance by decreasing sleep time ``` $ git shortlog -s v0.3.0...v0.4.0 15 John Reese 1 Justin Kula 1 Richard Schwab ``` v0.3.0 ------ Feature release v0.3.0: - Cursors can be used as context managers ``` $ git shortlog -s v0.2.2...v0.3.0 6 John Reese 5 Linus Lewandowski ``` v0.2.2 ------ Minor release: - Correct aiosqlite.__version__ - Markdown readme, release via twine ``` $ git shortlog -s v0.2.1...v0.2.2 5 John Reese ``` v0.2.1 ------ Minor release v0.2.1: - Increase polling speed on event loop - Using black and pylint ``` $ git shortlog -s v0.2.0...v0.2.1 8 John Reese 2 Pavol Vargovcik ``` v0.2.0 ------ Beta version 0.2.0 ``` $ git shortlog -s c606de200b7afe6d73a6e2900557d622c62ed78c...v0.2.0 1 John Reese ``` aiosqlite-0.11.0/CODE_OF_CONDUCT.md000066400000000000000000000062141357435633100163770ustar00rootroot00000000000000# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at john@noswap.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ aiosqlite-0.11.0/CONTRIBUTING.md000066400000000000000000000017321357435633100160310ustar00rootroot00000000000000# Contributing to aiosqlite ## Preparation You'll need to have Python 3.5 available for testing. You can do this with [pyenv][]: $ pyenv install 3.5.6 $ pyenv shell 3.5.6 ## Setup Once cloned, create a clean virtual environment and install the appropriate tools and dependencies: $ cd $ make dev $ source .py3/bin/activate ## Testing Once you've made changes, you should run unit tests, validate your type annotations, and ensure your code meets the appropriate style and linting rules: $ make test lint ## Submitting Before submitting a pull request, please ensure that you have done the following: * Documented changes or features in README.md * Added appropriate license headers to new files * Written or modified tests for new functionality * Used [black][] to format code appropriately * Validated code with `make test lint` [black]: https://github.com/ambv/black [pyenv]: https://github.com/pyenv/pyenv aiosqlite-0.11.0/LICENSE000066400000000000000000000020531357435633100146020ustar00rootroot00000000000000MIT License Copyright (c) 2017 John Reese Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. aiosqlite-0.11.0/MANIFEST.in000066400000000000000000000000321357435633100153260ustar00rootroot00000000000000include README.md LICENSE aiosqlite-0.11.0/README.md000066400000000000000000000061411357435633100150560ustar00rootroot00000000000000aiosqlite ========= AsyncIO bridge to the standard `sqlite3` module for Python 3.5+ [![pypi release](https://img.shields.io/pypi/v/aiosqlite.svg)](https://pypi.org/project/aiosqlite) [![changelog](https://img.shields.io/badge/change-log-blue)](https://github.com/jreese/aiosqlite/blob/master/CHANGELOG.md) [![code coverage](https://img.shields.io/codecov/c/github/jreese/aiosqlite/master.svg)](https://codecov.io/gh/jreese/aiosqlite) [![build status](https://github.com/jreese/aiosqlite/workflows/Build/badge.svg)](https://github.com/jreese/aiosqlite/actions) [![MIT license](https://img.shields.io/pypi/l/aiosqlite.svg)](https://github.com/jreese/aiosqlite/blob/master/LICENSE) [![code style black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) Install ------- aiosqlite is compatible with Python 3.5 and newer. You can install it from PyPI with the following command: $ pip install aiosqlite Usage ----- aiosqlite replicates the standard `sqlite3` module, but with async versions of all the standard connection and cursor methods, and context managers for automatically closing connections: ```python async with aiosqlite.connect(...) as db: await db.execute('INSERT INTO some_table ...') await db.commit() async with db.execute('SELECT * FROM some_table') as cursor: async for row in cursor: ... ``` Alternately, you can continue using connections and cursors more procedurally: ```python db = await aiosqlite.connect(...) cursor = await db.execute('SELECT * FROM some_table') row = await cursor.fetchone() rows = await cursor.fetchall() await cursor.close() await db.close() ``` aiosqlite also replicates most of the standard connection properties, as needed for advanced use cases like row or text factories, or for tracking the total number of rows inserted, modified, or deleted: ```python async with aiosqlite.connect(...) as db: db.row_factory = aiosqlite.Row async with db.execute('SELECT * FROM some_table') as cursor: value = row['column'] await db.execute('INSERT INTO foo some_table') assert db.total_changes > 0 ``` Details ------- aiosqlite allows interaction with SQLite databases on the main AsyncIO event loop without blocking execution of other coroutines while waiting for queries or data fetches. It does this by using a single, shared thread per connection. This thread executes all actions within a shared request queue to prevent overlapping actions. Connection objects are proxies to the real connections, contain the shared execution thread, and provide context managers to handle automatically closing connections. Cursors are similarly proxies to the real cursors, and provide async iterators to query results. License ------- aiosqlite is copyright [John Reese](https://jreese.sh), and licensed under the MIT license. I am providing code in this repository to you under an open source license. This is my personal repository; the license you receive to my code is from me and not from my employer. See the `LICENSE` file for details. aiosqlite-0.11.0/aiosqlite/000077500000000000000000000000001357435633100155675ustar00rootroot00000000000000aiosqlite-0.11.0/aiosqlite/__init__.py000066400000000000000000000014271357435633100177040ustar00rootroot00000000000000# Copyright 2018 John Reese # Licensed under the MIT license """asyncio bridge to sqlite3""" from sqlite3 import ( # pylint: disable=redefined-builtin register_adapter, register_converter, sqlite_version, sqlite_version_info, Row, Warning, Error, DatabaseError, IntegrityError, ProgrammingError, OperationalError, NotSupportedError, ) from .core import connect, Connection, Cursor __version__ = "0.11.0" __all__ = [ "__version__", "register_adapter", "register_converter", "sqlite_version", "sqlite_version_info", "connect", "Connection", "Cursor", "Row", "Warning", "Error", "DatabaseError", "IntegrityError", "ProgrammingError", "OperationalError", "NotSupportedError", ] aiosqlite-0.11.0/aiosqlite/context.py000066400000000000000000000020621357435633100176250ustar00rootroot00000000000000# Copyright 2018 # Licensed under the MIT license from collections.abc import Coroutine from functools import wraps class ContextManager(Coroutine): __slots__ = ("_coro", "_obj") def __init__(self, coro): self._coro = coro self._obj = None def send(self, value): return self._coro.send(value) def throw(self, typ, val=None, tb=None): if val is None: return self._coro.throw(typ) if tb is None: return self._coro.throw(typ, val) return self._coro.throw(typ, val, tb) def close(self): return self._coro.close() def __await__(self): return self._coro.__await__() async def __aenter__(self): self._obj = await self._coro return self._obj async def __aexit__(self, exc_type, exc, tb): await self._obj.close() self._obj = None def contextmanager(method): @wraps(method) def wrapper(self, *args, **kwargs) -> ContextManager: return ContextManager(method(self, *args, **kwargs)) return wrapper aiosqlite-0.11.0/aiosqlite/core.py000066400000000000000000000234311357435633100170740ustar00rootroot00000000000000# Copyright 2018 John Reese # Licensed under the MIT license """ Core implementation of aiosqlite proxies """ import asyncio import logging import sqlite3 from functools import partial from pathlib import Path from queue import Queue, Empty from threading import Thread from typing import Any, Callable, Generator, Iterable, Optional, Tuple, Type, Union from .context import contextmanager __all__ = ["connect", "Connection", "Cursor"] LOG = logging.getLogger("aiosqlite") class Cursor: def __init__(self, conn: "Connection", cursor: sqlite3.Cursor) -> None: self._conn = conn self._cursor = cursor def __aiter__(self) -> "Cursor": """The cursor proxy is also an async iterator.""" return self async def __anext__(self) -> sqlite3.Row: """Use `cursor.fetchone()` to provide an async iterable.""" row = await self.fetchone() if row is None: raise StopAsyncIteration return row async def _execute(self, fn, *args, **kwargs): """Execute the given function on the shared connection's thread.""" return await self._conn._execute(fn, *args, **kwargs) async def execute(self, sql: str, parameters: Iterable[Any] = None) -> None: """Execute the given query.""" if parameters is None: parameters = [] await self._execute(self._cursor.execute, sql, parameters) async def executemany(self, sql: str, parameters: Iterable[Iterable[Any]]) -> None: """Execute the given multiquery.""" await self._execute(self._cursor.executemany, sql, parameters) async def executescript(self, sql_script: str) -> None: """Execute a user script.""" await self._execute(self._cursor.executescript, sql_script) async def fetchone(self) -> Optional[sqlite3.Row]: """Fetch a single row.""" return await self._execute(self._cursor.fetchone) async def fetchmany(self, size: int = None) -> Iterable[sqlite3.Row]: """Fetch up to `cursor.arraysize` number of rows.""" args = () # type: Tuple[int, ...] if size is not None: args = (size,) return await self._execute(self._cursor.fetchmany, *args) async def fetchall(self) -> Iterable[sqlite3.Row]: """Fetch all remaining rows.""" return await self._execute(self._cursor.fetchall) async def close(self) -> None: """Close the cursor.""" await self._execute(self._cursor.close) @property def rowcount(self) -> int: return self._cursor.rowcount @property def lastrowid(self) -> int: return self._cursor.lastrowid @property def arraysize(self) -> int: return self._cursor.arraysize @arraysize.setter def arraysize(self, value: int) -> None: self._cursor.arraysize = value @property def description(self) -> Tuple[Tuple]: return self._cursor.description @property def connection(self) -> sqlite3.Connection: return self._cursor.connection async def __aenter__(self): return self async def __aexit__(self, exc_type, exc_val, exc_tb): await self.close() class Connection(Thread): def __init__( self, connector: Callable[[], sqlite3.Connection], loop: asyncio.AbstractEventLoop, ) -> None: super().__init__() self._running = True self._connection = None # type: Optional[sqlite3.Connection] self._connector = connector self._loop = loop self._tx = Queue() # type: Queue @property def _conn(self) -> sqlite3.Connection: if self._connection is None: raise ValueError("no active connection") return self._connection def _execute_insert( self, sql: str, parameters: Iterable[Any] ) -> Optional[sqlite3.Row]: cursor = self._conn.execute(sql, parameters) cursor.execute("SELECT last_insert_rowid()") return cursor.fetchone() def _execute_fetchall( self, sql: str, parameters: Iterable[Any] ) -> Iterable[sqlite3.Row]: cursor = self._conn.execute(sql, parameters) return cursor.fetchall() def run(self) -> None: """Execute function calls on a separate thread.""" while self._running: try: future, function = self._tx.get(timeout=0.1) except Empty: continue try: LOG.debug("executing %s", function) result = function() LOG.debug("returning %s", result) self._loop.call_soon_threadsafe(future.set_result, result) except BaseException as e: LOG.exception("returning exception %s", e) self._loop.call_soon_threadsafe(future.set_exception, e) async def _execute(self, fn, *args, **kwargs): """Queue a function with the given arguments for execution.""" function = partial(fn, *args, **kwargs) future = self._loop.create_future() self._tx.put_nowait((future, function)) return await future async def _connect(self) -> "Connection": """Connect to the actual sqlite database.""" if self._connection is None: self._connection = await self._execute(self._connector) return self def __await__(self) -> Generator[Any, None, "Connection"]: self.start() return self._connect().__await__() async def __aenter__(self) -> "Connection": return await self async def __aexit__(self, exc_type, exc_val, exc_tb) -> None: await self.close() @contextmanager async def cursor(self) -> Cursor: """Create an aiosqlite cursor wrapping a sqlite3 cursor object.""" return Cursor(self, await self._execute(self._conn.cursor)) async def commit(self) -> None: """Commit the current transaction.""" await self._execute(self._conn.commit) async def rollback(self) -> None: """Roll back the current transaction.""" await self._execute(self._conn.rollback) async def close(self) -> None: """Complete queued queries/cursors and close the connection.""" await self._execute(self._conn.close) self._running = False self._connection = None @contextmanager async def execute(self, sql: str, parameters: Iterable[Any] = None) -> Cursor: """Helper to create a cursor and execute the given query.""" if parameters is None: parameters = [] cursor = await self._execute(self._conn.execute, sql, parameters) return Cursor(self, cursor) @contextmanager async def execute_insert( self, sql: str, parameters: Iterable[Any] = None ) -> Optional[sqlite3.Row]: """Helper to insert and get the last_insert_rowid.""" if parameters is None: parameters = [] return await self._execute(self._execute_insert, sql, parameters) @contextmanager async def execute_fetchall( self, sql: str, parameters: Iterable[Any] = None ) -> Iterable[sqlite3.Row]: """Helper to execute a query and return all the data.""" if parameters is None: parameters = [] return await self._execute(self._execute_fetchall, sql, parameters) @contextmanager async def executemany( self, sql: str, parameters: Iterable[Iterable[Any]] ) -> Cursor: """Helper to create a cursor and execute the given multiquery.""" cursor = await self._execute(self._conn.executemany, sql, parameters) return Cursor(self, cursor) @contextmanager async def executescript(self, sql_script: str) -> Cursor: """Helper to create a cursor and execute a user script.""" cursor = await self._execute(self._conn.executescript, sql_script) return Cursor(self, cursor) async def interrupt(self) -> None: """Interrupt pending queries.""" return self._conn.interrupt() @property def in_transaction(self) -> bool: return self._conn.in_transaction @property def isolation_level(self) -> str: return self._conn.isolation_level @isolation_level.setter def isolation_level(self, value: str) -> None: self._conn.isolation_level = value @property def row_factory(self) -> "Optional[Type]": # py3.5.2 compat (#24) return self._conn.row_factory @row_factory.setter def row_factory(self, factory: "Optional[Type]") -> None: # py3.5.2 compat (#24) self._conn.row_factory = factory @property def text_factory(self) -> Type: return self._conn.text_factory @text_factory.setter def text_factory(self, factory: Type) -> None: self._conn.text_factory = factory @property def total_changes(self) -> int: return self._conn.total_changes async def enable_load_extension(self, value: bool) -> None: await self._execute(self._conn.enable_load_extension, value) # type: ignore async def load_extension(self, path: str): await self._execute(self._conn.load_extension, path) # type: ignore async def set_progress_handler( self, handler: Callable[[], Optional[int]], n: int ) -> None: await self._execute(self._conn.set_progress_handler, handler, n) def connect( database: Union[str, Path], *, loop: asyncio.AbstractEventLoop = None, **kwargs: Any ) -> Connection: """Create and return a connection proxy to the sqlite database.""" if loop is None: loop = asyncio.get_event_loop() def connector() -> sqlite3.Connection: if isinstance(database, str): loc = database elif isinstance(database, bytes): loc = database.decode("utf-8") else: loc = str(database) return sqlite3.connect(loc, **kwargs) return Connection(connector, loop) aiosqlite-0.11.0/aiosqlite/tests/000077500000000000000000000000001357435633100167315ustar00rootroot00000000000000aiosqlite-0.11.0/aiosqlite/tests/__init__.py000066400000000000000000000001331357435633100210370ustar00rootroot00000000000000# Copyright 2018 John Reese # Licensed under the MIT license from .smoke import SmokeTest aiosqlite-0.11.0/aiosqlite/tests/__main__.py000066400000000000000000000002431357435633100210220ustar00rootroot00000000000000# Copyright 2018 John Reese # Licensed under the MIT license import unittest if __name__ == "__main__": unittest.main(module="aiosqlite.tests", verbosity=2) aiosqlite-0.11.0/aiosqlite/tests/helpers.py000066400000000000000000000013231357435633100207440ustar00rootroot00000000000000# Copyright 2018 John Reese # Licensed under the MIT license import logging import sys def setup_logger(): log = logging.getLogger("") log.setLevel(logging.INFO) logging.addLevelName(logging.ERROR, "E") logging.addLevelName(logging.WARNING, "W") logging.addLevelName(logging.INFO, "I") logging.addLevelName(logging.DEBUG, "V") date_fmt = r"%H:%M:%S" verbose_fmt = ( "%(asctime)s,%(msecs)d %(levelname)s " "%(module)s:%(funcName)s():%(lineno)d " "%(message)s" ) handler = logging.StreamHandler(sys.stdout) handler.setLevel(logging.INFO) handler.setFormatter(logging.Formatter(verbose_fmt, date_fmt)) log.addHandler(handler) return log aiosqlite-0.11.0/aiosqlite/tests/perf.py000066400000000000000000000111221357435633100202340ustar00rootroot00000000000000# Copyright 2018 John Reese # Licensed under the MIT license """ Simple perf tests for aiosqlite and the asyncio run loop. """ import aiosqlite import aiounittest import time from pathlib import Path from .smoke import setup_logger TEST_DB = Path(":memory:") TARGET = 2.0 RESULTS = {} def timed(fn): """ Decorator for perf testing a block of async code. Expects the wrapped function to return an async generator. The generator should do setup, then yield when ready to start perf testing. The decorator will then pump the generator repeatedly until the target time has been reached, then close the generator and print perf results. """ name = fn.__name__ async def wrapper(*args, **kwargs): gen = fn(*args, **kwargs) await gen.asend(None) count = 0 before = time.time() while True: count += 1 value = time.time() - before < TARGET try: if value: await gen.asend(value) else: await gen.aclose() break except StopAsyncIteration: break except Exception as e: print(f"exception occurred: {e}") return duration = time.time() - before RESULTS[name] = (count, duration) return wrapper class PerfTest(aiounittest.AsyncTestCase): @classmethod def setUpClass(cls): print(f"Running perf tests for at least {TARGET:.1f}s each...") setup_logger() @classmethod def tearDownClass(cls): print(f"\n{'Perf Test':<25} Iterations Duration {'Rate':>11}") for name in sorted(RESULTS): count, duration = RESULTS[name] rate = count / duration name = name.replace("test_", "") print(f"{name:<25} {count:>10} {duration:>7.1f}s {rate:>9.1f}/s") def setUp(self): if TEST_DB.exists(): TEST_DB.unlink() @timed async def test_atomics(self): async with aiosqlite.connect(TEST_DB) as db: await db.execute("create table perf (i integer primary key asc, k integer)") await db.execute("insert into perf (k) values (2), (3)") await db.commit() while True: yield async with db.execute("select last_insert_rowid()") as cursor: _row_id = await cursor.fetchone() @timed async def test_inserts(self): async with aiosqlite.connect(TEST_DB) as db: await db.execute("create table perf (i integer primary key asc, k integer)") await db.commit() while True: yield await db.execute("insert into perf (k) values (1), (2), (3)") await db.commit() @timed async def test_insert_ids(self): async with aiosqlite.connect(TEST_DB) as db: await db.execute("create table perf (i integer primary key asc, k integer)") await db.commit() while True: yield cursor = await db.execute("insert into perf (k) values (1)") await cursor.execute("select last_insert_rowid()") await cursor.fetchone() await db.commit() @timed async def test_insert_macro_ids(self): async with aiosqlite.connect(TEST_DB) as db: await db.execute("create table perf (i integer primary key asc, k integer)") await db.commit() while True: yield await db.execute_insert("insert into perf (k) values (1)") await db.commit() @timed async def test_select(self): async with aiosqlite.connect(TEST_DB) as db: await db.execute("create table perf (i integer primary key asc, k integer)") for i in range(100): await db.execute("insert into perf (k) values (%d)" % (i,)) await db.commit() while True: yield cursor = await db.execute("select i, k from perf") assert len(await cursor.fetchall()) == 100 @timed async def test_select_macro(self): async with aiosqlite.connect(TEST_DB) as db: await db.execute("create table perf (i integer primary key asc, k integer)") for i in range(100): await db.execute("insert into perf (k) values (%d)" % (i,)) await db.commit() while True: yield assert len(await db.execute_fetchall("select i, k from perf")) == 100 aiosqlite-0.11.0/aiosqlite/tests/smoke.py000066400000000000000000000205251357435633100204250ustar00rootroot00000000000000# Copyright 2018 John Reese # Licensed under the MIT license from sqlite3 import OperationalError from unittest import SkipTest import aiosqlite import aiounittest import asyncio from pathlib import Path from .helpers import setup_logger TEST_DB = Path("test.db") # pypy uses non-standard text factory for low-level sqlite implementation try: from _sqlite3 import _unicode_text_factory as default_text_factory except ImportError: default_text_factory = str class SmokeTest(aiounittest.AsyncTestCase): @classmethod def setUpClass(cls): setup_logger() def setUp(self): if TEST_DB.exists(): TEST_DB.unlink() def tearDown(self): if TEST_DB.exists(): TEST_DB.unlink() async def test_connection_await(self): db = await aiosqlite.connect(TEST_DB) self.assertIsInstance(db, aiosqlite.Connection) async with db.execute("select 1, 2") as cursor: rows = await cursor.fetchall() self.assertEqual(rows, [(1, 2)]) await db.close() async def test_connection_context(self): async with aiosqlite.connect(TEST_DB) as db: self.assertIsInstance(db, aiosqlite.Connection) async with db.execute("select 1, 2") as cursor: rows = await cursor.fetchall() self.assertEqual(rows, [(1, 2)]) async def test_connection_locations(self): class Fake: # pylint: disable=too-few-public-methods def __str__(self): return str(TEST_DB) locs = ("test.db", b"test.db", Path("test.db"), Fake()) async with aiosqlite.connect(TEST_DB) as db: await db.execute("create table foo (i integer, k integer)") await db.execute("insert into foo (i, k) values (1, 5)") await db.commit() cursor = await db.execute("select * from foo") rows = await cursor.fetchall() for loc in locs: async with aiosqlite.connect(loc) as db: cursor = await db.execute("select * from foo") self.assertEqual(await cursor.fetchall(), rows) async def test_multiple_connections(self): async with aiosqlite.connect(TEST_DB) as db: await db.execute( "create table multiple_connections " "(i integer primary key asc, k integer)" ) async def do_one_conn(i): async with aiosqlite.connect(TEST_DB) as db: await db.execute("insert into multiple_connections (k) values (?)", [i]) await db.commit() await asyncio.gather(*[do_one_conn(i) for i in range(10)]) async with aiosqlite.connect(TEST_DB) as db: cursor = await db.execute("select * from multiple_connections") rows = await cursor.fetchall() assert len(rows) == 10 async def test_multiple_queries(self): async with aiosqlite.connect(TEST_DB) as db: await db.execute( "create table multiple_queries " "(i integer primary key asc, k integer)" ) await asyncio.gather( *[ db.execute("insert into multiple_queries (k) values (?)", [i]) for i in range(10) ] ) await db.commit() async with aiosqlite.connect(TEST_DB) as db: cursor = await db.execute("select * from multiple_queries") rows = await cursor.fetchall() assert len(rows) == 10 async def test_iterable_cursor(self): async with aiosqlite.connect(TEST_DB) as db: cursor = await db.cursor() await cursor.execute( "create table iterable_cursor " "(i integer primary key asc, k integer)" ) await cursor.executemany( "insert into iterable_cursor (k) values (?)", [[i] for i in range(10)] ) await db.commit() async with aiosqlite.connect(TEST_DB) as db: cursor = await db.execute("select * from iterable_cursor") rows = [] async for row in cursor: rows.append(row) assert len(rows) == 10 async def test_context_cursor(self): async with aiosqlite.connect(TEST_DB) as db: async with db.cursor() as cursor: await cursor.execute( "create table context_cursor " "(i integer primary key asc, k integer)" ) await cursor.executemany( "insert into context_cursor (k) values (?)", [[i] for i in range(10)], ) await db.commit() async with aiosqlite.connect(TEST_DB) as db: async with db.execute("select * from context_cursor") as cursor: rows = [] async for row in cursor: rows.append(row) assert len(rows) == 10 async def test_connection_properties(self): async with aiosqlite.connect(TEST_DB) as db: self.assertEqual(db.total_changes, 0) async with db.cursor() as cursor: self.assertFalse(db.in_transaction) await cursor.execute( "create table test_properties " "(i integer primary key asc, k integer, d text)" ) await cursor.execute( "insert into test_properties (k, d) values (1, 'hi')" ) self.assertTrue(db.in_transaction) await db.commit() self.assertFalse(db.in_transaction) self.assertEqual(db.total_changes, 1) self.assertIsNone(db.row_factory) self.assertEqual(db.text_factory, default_text_factory) async with db.cursor() as cursor: await cursor.execute("select * from test_properties") row = await cursor.fetchone() self.assertIsInstance(row, tuple) self.assertEqual(row, (1, 1, "hi")) with self.assertRaises(TypeError): _ = row["k"] db.row_factory = aiosqlite.Row db.text_factory = bytes self.assertEqual(db.row_factory, aiosqlite.Row) self.assertEqual(db.text_factory, bytes) async with db.cursor() as cursor: await cursor.execute("select * from test_properties") row = await cursor.fetchone() self.assertIsInstance(row, aiosqlite.Row) self.assertEqual(row[1], 1) self.assertEqual(row[2], b"hi") self.assertEqual(row["k"], 1) self.assertEqual(row["d"], b"hi") async def test_fetch_all(self): async with aiosqlite.connect(TEST_DB) as db: await db.execute( "create table test_fetch_all (i integer primary key asc, k integer)" ) await db.execute( "insert into test_fetch_all (k) values (10), (24), (16), (32)" ) await db.commit() async with aiosqlite.connect(TEST_DB) as db: cursor = await db.execute("select k from test_fetch_all where k < 30") rows = await cursor.fetchall() self.assertEqual(rows, [(10,), (24,), (16,)]) async def test_enable_load_extension(self): """Assert that after enabling extension loading, they can be loaded""" async with aiosqlite.connect(TEST_DB) as db: try: await db.enable_load_extension(True) await db.load_extension("test") except OperationalError as e: assert "not authorized" not in e.args except AttributeError: raise SkipTest( "python was not compiled with sqlite3 " "extension support, so we can't test it" ) async def test_set_progress_handler(self): """Assert that after setting a progress handler returning 1, DB operations are aborted""" async with aiosqlite.connect(TEST_DB) as db: await db.set_progress_handler(lambda: 1, 1) with self.assertRaises(OperationalError): await db.execute( "create table test_progress_handler (i integer primary key asc, k integer)" ) aiosqlite-0.11.0/makefile000066400000000000000000000017021357435633100152750ustar00rootroot00000000000000venv: python -m venv .venv source .venv/bin/activate && make setup dev echo 'run `source .venv/bin/activate` to develop aiosqlite' setup: python -m pip install -Ur requirements-dev.txt if python -V | grep -v "3.5"; then python -m pip install -U black; fi dev: python setup.py develop release: lint test clean python setup.py sdist python -m twine upload dist/* format: python -m isort --apply --recursive aiosqlite setup.py python -m black aiosqlite setup.py lint: python -m pylint --rcfile .pylint aiosqlite/*.py setup.py if python -V | grep -v "3.5"; then python -m isort --diff --recursive aiosqlite setup.py; fi if python -V | grep -v "3.5"; then python -m black --check aiosqlite setup.py; fi test: python -m coverage run -m aiosqlite.tests python -m coverage report python -m mypy aiosqlite/*.py perf: python -m unittest -v aiosqlite.tests.perf clean: rm -rf build dist README MANIFEST *.egg-info distclean: clean rm -rf .venv aiosqlite-0.11.0/requirements-dev.txt000066400000000000000000000001561357435633100176370ustar00rootroot00000000000000aiounittest==1.3.0 codecov==2.0.15 coverage==4.5.4 mypy==0.740 pylint==2.4.3 twine==1.15.0 # pyup: >=1.15,<2 aiosqlite-0.11.0/setup.cfg000066400000000000000000000010361357435633100154160ustar00rootroot00000000000000[coverage:run] branch = True include = aiosqlite/* omit = aiosqlite/tests/* [coverage:report] fail_under = 75 precision = 1 show_missing = True skip_covered = True [isort] line_length = 88 multi_line_output = 3 force_grid_wrap = False include_trailing_comma = True use_parentheses = True [mypy] ignore_missing_imports = True [mypy-aiosqlite.tests.perf] follow_imports = silent [ptr] entry_point_module = aiosqlite/__init__ test_suite = tests test_suite_timeout = 120 run_black = true run_mypy = true run_flake8 = false run_pylint = true aiosqlite-0.11.0/setup.py000066400000000000000000000023361357435633100153130ustar00rootroot00000000000000from setuptools import setup with open("README.md") as f: readme = f.read() with open("aiosqlite/__init__.py") as f: for line in f: if line.startswith("__version__"): version = line.split('"')[1] setup( name="aiosqlite", description="asyncio bridge to the standard sqlite3 module", long_description=readme, long_description_content_type="text/markdown", version=version, author="John Reese", author_email="john@noswap.com", url="https://github.com/jreese/aiosqlite", classifiers=[ "Development Status :: 4 - Beta", "Framework :: AsyncIO", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Libraries", ], license="MIT", packages=["aiosqlite", "aiosqlite.tests"], python_requires=">=3.5", setup_requires=["setuptools>=38.6.0"], tests_require=["aiounittest"], install_requires=[], test_suite="aiosqlite.tests", )