Mastering Python Second Edition Release Code
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
Chapter 18, Packaging
|
||||
##############################################################################
|
||||
|
||||
| Creating your own Libraries/Applications demonstrates the usage of setuptools and setup.py to build and deploy packages to the Python Package Index (PyPI).
|
||||
@@ -0,0 +1,7 @@
|
||||
import sys
|
||||
import pathlib
|
||||
|
||||
# Little hack to add the current directory to sys.path so we can
|
||||
# find the imports
|
||||
path = pathlib.Path(__file__).parent
|
||||
sys.path.append(str(path.resolve()))
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
[[package]]
|
||||
name = "atomicwrites"
|
||||
version = "1.4.0"
|
||||
description = "Atomic file writes."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "attrs"
|
||||
version = "21.2.0"
|
||||
description = "Classes Without Boilerplate"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[package.extras]
|
||||
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit"]
|
||||
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
|
||||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface"]
|
||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins"]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.4"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "more-itertools"
|
||||
version = "8.11.0"
|
||||
description = "More routines for operating on iterables, beyond itertools"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "21.3"
|
||||
description = "Core utilities for Python packages"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.dependencies]
|
||||
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "0.13.1"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
|
||||
[[package]]
|
||||
name = "progressbar2"
|
||||
version = "3.55.0"
|
||||
description = "A Python Progressbar library to provide visual (yet text based) progress to long running operations."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
python-utils = ">=2.3.0"
|
||||
six = "*"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx (>=1.7.4)"]
|
||||
tests = ["flake8 (>=3.7.7)", "pytest (>=4.6.9)", "pytest-cov (>=2.6.1)", "freezegun (>=0.3.11)", "sphinx (>=1.8.5)"]
|
||||
|
||||
[[package]]
|
||||
name = "py"
|
||||
version = "1.11.0"
|
||||
description = "library with cross-python path, ini-parsing, io, code, log facilities"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "pyparsing"
|
||||
version = "3.0.6"
|
||||
description = "Python parsing module"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
|
||||
[package.extras]
|
||||
diagrams = ["jinja2", "railroad-diagrams"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "5.4.3"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.dependencies]
|
||||
atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
|
||||
attrs = ">=17.4.0"
|
||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
more-itertools = ">=4.0.0"
|
||||
packaging = "*"
|
||||
pluggy = ">=0.12,<1.0"
|
||||
py = ">=1.5.0"
|
||||
wcwidth = "*"
|
||||
|
||||
[package.extras]
|
||||
checkqa-mypy = ["mypy (==v0.761)"]
|
||||
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "python-utils"
|
||||
version = "2.5.6"
|
||||
description = "Python Utils is a module with some convenient utilities not included with the standard Python install"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
six = "*"
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "wcwidth"
|
||||
version = "0.2.5"
|
||||
description = "Measures the displayed width of unicode strings in a terminal"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "3d22a924f04cd5a8d33524dbca1e28148fd6580a13000f8705266c773e6a7105"
|
||||
|
||||
[metadata.files]
|
||||
atomicwrites = [
|
||||
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
|
||||
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
|
||||
]
|
||||
attrs = [
|
||||
{file = "attrs-21.2.0-py2.py3-none-any.whl", hash = "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1"},
|
||||
{file = "attrs-21.2.0.tar.gz", hash = "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb"},
|
||||
]
|
||||
colorama = [
|
||||
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
||||
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
||||
]
|
||||
more-itertools = [
|
||||
{file = "more-itertools-8.11.0.tar.gz", hash = "sha256:0a2fd25d343c08d7e7212071820e7e7ea2f41d8fb45d6bc8a00cd6ce3b7aab88"},
|
||||
{file = "more_itertools-8.11.0-py3-none-any.whl", hash = "sha256:88afff98d83d08fe5e4049b81e2b54c06ebb6b3871a600040865c7a592061cbb"},
|
||||
]
|
||||
packaging = [
|
||||
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
|
||||
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
|
||||
]
|
||||
pluggy = [
|
||||
{file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"},
|
||||
{file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"},
|
||||
]
|
||||
progressbar2 = [
|
||||
{file = "progressbar2-3.55.0-py2.py3-none-any.whl", hash = "sha256:e98fee031da31ab9138fd8dd838ac80eafba82764eb75a43d25e3ca622f47d14"},
|
||||
{file = "progressbar2-3.55.0.tar.gz", hash = "sha256:86835d1f1a9317ab41aeb1da5e4184975e2306586839d66daf63067c102f8f04"},
|
||||
]
|
||||
py = [
|
||||
{file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
|
||||
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
|
||||
]
|
||||
pyparsing = [
|
||||
{file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"},
|
||||
{file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"},
|
||||
]
|
||||
pytest = [
|
||||
{file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"},
|
||||
{file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"},
|
||||
]
|
||||
python-utils = [
|
||||
{file = "python-utils-2.5.6.tar.gz", hash = "sha256:352d5b1febeebf9b3cdb9f3c87a3b26ef22d3c9e274a8ec1e7048ecd2fac4349"},
|
||||
{file = "python_utils-2.5.6-py2.py3-none-any.whl", hash = "sha256:18fbc1a1df9a9061e3059a48ebe5c8a66b654d688b0e3ecca8b339a7f168f208"},
|
||||
]
|
||||
six = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
]
|
||||
wcwidth = [
|
||||
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
|
||||
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
|
||||
]
|
||||
@@ -0,0 +1,29 @@
|
||||
[tool.poetry]
|
||||
name = "T_00_basic_pyproject"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Rick van Hattem <Wolph@wol.ph>"]
|
||||
packages = [
|
||||
{include="T_00_basic_pyproject"},
|
||||
{include="some_directory/**/*.py"},
|
||||
]
|
||||
|
||||
include = ["CHANGELOG.rst"]
|
||||
exclude = ["T_00_basic_pyproject/local.py"]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
progressbar2 = "^3.5"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^5.2"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
our_command = 'T_00_basic_pyproject.main:run'
|
||||
|
||||
[tool.poetry.urls]
|
||||
docs='https://progressbar-2.readthedocs.io/'
|
||||
@@ -0,0 +1 @@
|
||||
__version__ = '0.1.0'
|
||||
@@ -0,0 +1,5 @@
|
||||
from t_00_basic_pyproject import __version__
|
||||
|
||||
|
||||
def test_version():
|
||||
assert __version__ == '0.1.0'
|
||||
@@ -0,0 +1,15 @@
|
||||
import pathlib
|
||||
import setuptools
|
||||
|
||||
# Get the current directory
|
||||
PROJECT_PATH = pathlib.Path(__file__).parent
|
||||
|
||||
# Create the extension object with the references to the C source
|
||||
sum_of_squares = setuptools.Extension('sum_of_squares', sources=[
|
||||
# Get the relative path to sum_of_squares.c
|
||||
str(PROJECT_PATH / 'sum_of_squares.c'),
|
||||
])
|
||||
|
||||
|
||||
def build(setup_kwargs):
|
||||
setup_kwargs['ext_modules'] = [sum_of_squares]
|
||||
@@ -0,0 +1,7 @@
|
||||
import sys
|
||||
import pathlib
|
||||
|
||||
# Little hack to add the current directory to sys.path so we can
|
||||
# find the imports
|
||||
path = pathlib.Path(__file__).parent
|
||||
sys.path.append(str(path.resolve()))
|
||||
@@ -0,0 +1,16 @@
|
||||
[tool.poetry]
|
||||
name = "T_01_pyproject_extensions"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Rick van Hattem <Wolph@wol.ph>"]
|
||||
build = "build_extension.py"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^5.2"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <Python.h>
|
||||
|
||||
static PyObject* sum_of_squares(PyObject *self, PyObject
|
||||
*args){
|
||||
/* Declare the variables */
|
||||
int n;
|
||||
int total = 0;
|
||||
|
||||
/* Parse the arguments */
|
||||
if(!PyArg_ParseTuple(args, "i", &n)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The actual summing code */
|
||||
for(int i=0; i<n; i++){
|
||||
if((i * i) < n){
|
||||
total += i * i;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the number but convert it to a Python object first
|
||||
*/
|
||||
return PyLong_FromLong(total);
|
||||
}
|
||||
|
||||
static PyMethodDef methods[] = {
|
||||
/* Register the function */
|
||||
{"sum_of_squares", sum_of_squares, METH_VARARGS,
|
||||
"Sum the perfect squares below n"},
|
||||
/* Indicate the end of the list */
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
static struct PyModuleDef module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"sum_of_squares", /* Module name */
|
||||
NULL, /* Module documentation */
|
||||
-1, /* Module state, -1 means global. This parameter is
|
||||
for sub-interpreters */
|
||||
methods,
|
||||
};
|
||||
|
||||
/* Initialize the module */
|
||||
PyMODINIT_FUNC PyInit_sum_of_squares(void){
|
||||
return PyModule_Create(&module);
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
__version__ = '0.1.0'
|
||||
@@ -0,0 +1,5 @@
|
||||
from t_01_pyproject_extensions import __version__
|
||||
|
||||
|
||||
def test_version():
|
||||
assert __version__ == '0.1.0'
|
||||
@@ -0,0 +1,15 @@
|
||||
# Include all documentation files
|
||||
include-recursive *.rst
|
||||
include LICENSE
|
||||
|
||||
# Include docs and tests
|
||||
graft tests
|
||||
graft docs
|
||||
|
||||
# Skip compiled python files
|
||||
global-exclude *.py[co]
|
||||
|
||||
# Remove all build directories
|
||||
prune docs/_build
|
||||
prune build
|
||||
prune dist
|
||||
@@ -0,0 +1 @@
|
||||
Hi
|
||||
@@ -0,0 +1,4 @@
|
||||
>>> from importlib import metadata
|
||||
|
||||
>>> metadata.entry_points()['our.custom.plugins']
|
||||
[EntryPoint(name='some_plugin', value='...some_plugin:run', ...]
|
||||
@@ -0,0 +1,3 @@
|
||||
[build-system]
|
||||
requires = ["setuptools", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
@@ -0,0 +1,40 @@
|
||||
import setuptools
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setuptools.setup(
|
||||
name='T_02_basic_setup_py',
|
||||
version='0.1.0',
|
||||
packages=setuptools.find_packages(),
|
||||
url='https://wol.ph/',
|
||||
author='Rick van Hattem',
|
||||
author_email='wolph@wol.ph',
|
||||
setup_requires=['pytest-runner'],
|
||||
install_requires=['portalocker'],
|
||||
extras_require={
|
||||
'docs': ['sphinx'],
|
||||
'tests': ['pytest'],
|
||||
},
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'our_command = T_02_basic_setup_py.main:run',
|
||||
],
|
||||
},
|
||||
include_package_data=True,
|
||||
package_data={
|
||||
# Include all documentation files
|
||||
'': ['*.rst'],
|
||||
|
||||
# Include docs and tests
|
||||
'tests': ['*'],
|
||||
'docs': ['*'],
|
||||
},
|
||||
exclude_package_data={
|
||||
'': ['*.pyc', '*.pyo'],
|
||||
'dist': ['*'],
|
||||
'build': ['*'],
|
||||
},
|
||||
project_urls=dict(
|
||||
docs='https://progressbar-2.readthedocs.io/',
|
||||
),
|
||||
)
|
||||
@@ -0,0 +1,46 @@
|
||||
[metadata]
|
||||
name = T_03_basic_setup_cfg
|
||||
version = 0.1.0
|
||||
url='https://wol.ph/',
|
||||
author='Rick van Hattem',
|
||||
author_email='wolph@wol.ph',
|
||||
|
||||
[build-system]
|
||||
requires =
|
||||
setuptools
|
||||
wheel
|
||||
|
||||
[options]
|
||||
packages = find:
|
||||
|
||||
install_requires =
|
||||
portalocker
|
||||
|
||||
include_package_data=True,
|
||||
|
||||
project_urls=
|
||||
docs=https://progressbar-2.readthedocs.io/
|
||||
|
||||
[options.extras_require]
|
||||
docs = sphinx
|
||||
tests = pytest
|
||||
|
||||
[options.entry_points]
|
||||
console_scripts =
|
||||
our_command = T_03_basic_setup_cfg.main:run
|
||||
|
||||
our.custom.plugins =
|
||||
some_plugin = T_03_basic_setup_cfg.some_plugin:run
|
||||
|
||||
[options.package_data]
|
||||
# Include all documentation files
|
||||
* = *.rst
|
||||
|
||||
# Include docs and tests
|
||||
tests = *
|
||||
docs = *
|
||||
|
||||
[options.exclude_package_data]
|
||||
* = *.pyc, *.pyo
|
||||
dist = *
|
||||
build = *
|
||||
@@ -0,0 +1,5 @@
|
||||
import setuptools
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setuptools.setup()
|
||||
@@ -0,0 +1,23 @@
|
||||
import pathlib
|
||||
import setuptools
|
||||
|
||||
# Get the current directory
|
||||
PROJECT_PATH = pathlib.Path(__file__).parent
|
||||
|
||||
|
||||
sum_of_squares = setuptools.Extension('sum_of_squares', sources=[
|
||||
# Get the relative path to sum_of_squares.c
|
||||
str(PROJECT_PATH / 'sum_of_squares.c'),
|
||||
])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setuptools.setup(
|
||||
name='T_04_C_extensions',
|
||||
version='0.1.0',
|
||||
packages=setuptools.find_packages(),
|
||||
url='https://wol.ph/',
|
||||
author='Rick van Hattem',
|
||||
author_email='wolph@wol.ph',
|
||||
ext_modules=[sum_of_squares],
|
||||
)
|
||||
@@ -0,0 +1,49 @@
|
||||
#include <Python.h>
|
||||
|
||||
static PyObject* sum_of_squares(PyObject *self, PyObject
|
||||
*args){
|
||||
/* Declare the variables */
|
||||
int n;
|
||||
int total = 0;
|
||||
|
||||
/* Parse the arguments */
|
||||
if(!PyArg_ParseTuple(args, "i", &n)){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The actual summing code */
|
||||
for(int i=0; i<n; i++){
|
||||
if((i * i) < n){
|
||||
total += i * i;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the number but convert it to a Python object first
|
||||
*/
|
||||
return PyLong_FromLong(total);
|
||||
}
|
||||
|
||||
static PyMethodDef methods[] = {
|
||||
/* Register the function */
|
||||
{"sum_of_squares", sum_of_squares, METH_VARARGS,
|
||||
"Sum the perfect squares below n"},
|
||||
/* Indicate the end of the list */
|
||||
{NULL, NULL, 0, NULL},
|
||||
};
|
||||
|
||||
static struct PyModuleDef module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"sum_of_squares", /* Module name */
|
||||
NULL, /* Module documentation */
|
||||
-1, /* Module state, -1 means global. This parameter is
|
||||
for sub-interpreters */
|
||||
methods,
|
||||
};
|
||||
|
||||
/* Initialize the module */
|
||||
PyMODINIT_FUNC PyInit_sum_of_squares(void){
|
||||
return PyModule_Create(&module);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Ignore C files since they are automatically generated by Cython
|
||||
*.c
|
||||
@@ -0,0 +1,14 @@
|
||||
#cython: language_level=3
|
||||
|
||||
|
||||
def sum_of_squares(int n):
|
||||
cdef int i, total = 0
|
||||
|
||||
for i in range(n):
|
||||
if i * i < n:
|
||||
total += i * i
|
||||
else:
|
||||
break
|
||||
|
||||
return total
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import sys
|
||||
import pathlib
|
||||
|
||||
# Little hack to add the current directory to sys.path so we can
|
||||
# find the imports
|
||||
path = pathlib.Path(__file__).parent
|
||||
sys.path.append(str(path.resolve()))
|
||||
@@ -0,0 +1,11 @@
|
||||
# python3
|
||||
|
||||
>>> import pyximport
|
||||
|
||||
>>> pyximport.install()
|
||||
(None, <pyximport.pyximport.PyxImporter object at ...>)
|
||||
|
||||
>>> from T_05_cython import sum_of_squares
|
||||
|
||||
>>> sum_of_squares.sum_of_squares(10)
|
||||
14
|
||||
@@ -0,0 +1,15 @@
|
||||
import setuptools
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
setuptools.setup(
|
||||
name='T_05_cython',
|
||||
version='0.1.0',
|
||||
ext_modules=[
|
||||
setuptools.Extension(
|
||||
'sum_of_squares',
|
||||
sources=['T_05_cython/sum_of_squares.pyx'],
|
||||
),
|
||||
],
|
||||
setup_requires=['cython'],
|
||||
)
|
||||
Reference in New Issue
Block a user