├── .circleci
└── config.yml
├── .gitignore
├── .gitmodules
├── LICENSE.txt
├── README.md
├── bin
└── mander
├── conda.recipe
├── meta.yaml
└── run_test.py
├── examples
├── .ipynb_checkpoints
│ └── Untitled-checkpoint.ipynb
└── demo.ipynb
├── lib
└── pybind11
│ ├── attr.h
│ ├── buffer_info.h
│ ├── cast.h
│ ├── chrono.h
│ ├── class_support.h
│ ├── common.h
│ ├── complex.h
│ ├── descr.h
│ ├── eigen.h
│ ├── embed.h
│ ├── eval.h
│ ├── functional.h
│ ├── numpy.h
│ ├── operators.h
│ ├── options.h
│ ├── pybind11.h
│ ├── pytypes.h
│ ├── stl.h
│ ├── stl_bind.h
│ └── typeid.h
├── mander
└── __init__.py
├── requirements.txt
├── setup.cfg
├── setup.py
├── src
└── pywrapper.cpp
└── test
├── __init__.py
├── data
├── CD_CA_24.geojson
├── CD_CA_24_scores.json
├── CD_CA_9.geojson
├── CD_CA_9_scores.json
├── CD_IL_4.geojson
├── CD_IL_4_scores.json
├── CD_MA_9.geojson
├── CD_MA_9_scores.json
├── CD_PA_7.geojson
├── CD_PA_7_scores.json
└── MN_Senate_2017.geojson
└── metrics.py
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | build:
4 | docker:
5 | # this docker image has compilers already cached and ready
6 | - image: conda/c3i-linux-64
7 |
8 | working_directory: ~/repo
9 |
10 | steps:
11 | - checkout
12 |
13 | # currently we have no external dependencies aside from two git submodules
14 | # - restore_cache:
15 | # keys:
16 | # - v1-dependencies-{{ checksum "environment.yml" }}
17 | # - v1-dependencies-
18 |
19 | - run:
20 | name: build recipe
21 | command: conda build conda.recipe
22 |
23 | # currently we have no external dependencies aside from two git submodules
24 | # - save_cache:
25 | # paths:
26 | # - /opt/conda
27 | # key: v1-dependencies-{{ checksum "environment.yml" }}
28 |
29 | # tests are run as part of the build process
30 | # - run:
31 | # name: run tests
32 | # command: |
33 | # source activate adj
34 | # pytest tests
35 |
36 | # we could potentially be uploading our build artifacts here. Maybe someday.
37 | - store_artifacts:
38 | path: test-reports
39 | destination: test-reports
40 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *__pycache__*
3 | *.pyc
4 | dist/
5 | build/
6 | mander.egg-info/
7 | *.so
8 | .Python
9 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "src/compactnesslib"]
2 | path = lib/compactnesslib
3 | url = https://github.com/r-barnes/compactnesslib.git
4 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017 MGGG, https://github.com/gerrymandr
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Mander
2 |
3 | A Python package and command line utility for calculating compactness metrics of
4 | electoral districts.
5 |
6 |
7 |
8 | # Example
9 |
10 | What scores are available?
11 |
12 | ```python
13 | import mander
14 | mander.getListOfScores()
15 | ```
16 |
17 | Getting scores for GeoJSON:
18 |
19 | ```python
20 | import mander
21 |
22 | geojson_data = """{ "type": "FeatureCollection", "features": [{"type": "Feature","properties": {},"geometry": { "type": "Polygon", "coordinates": [ [ [ -30.585937499999996, 27.68352808378776 ], [ -2.8125, 27.68352808378776 ], [ -2.8125, 46.800059446787316 ], [ -30.585937499999996, 46.800059446787316 ], [ -30.585937499999996, 27.68352808378776 ] ] ] } } ] }"""
23 |
24 | mander.getScoresForGeoJSON(geojson_data)
25 | ```
26 |
27 | Augmenting an existing shapefile with compactness scores:
28 |
29 | ```python
30 | import mander
31 | mander.augmentShapefileWithScores("us_electoral_districts.shp")
32 | ```
33 |
34 |
35 | # Compactness Metrics
36 |
37 | Compactness scores are calculated using the underlying
38 | [compactnesslib](https://github.com/r-barnes/compactnesslib)
39 | a list of the scores available and how they are calculated is available
40 | [here](https://github.com/r-barnes/compactnesslib/blob/master/Scores.md).
41 |
42 |
43 | # Developer Setup
44 |
45 | ## Requirements:
46 |
47 | * Python 2.7
48 | * pip
49 | * A compiler that supports C++ 11.
50 | * If using GCC, must use [version 4.9 or greater](https://github.com/nlohmann/json#supported-compilers).
51 |
52 | ## Recommended
53 | * virtualenv
54 |
55 | ## Steps:
56 |
57 | * Fork this repo
58 | * Clone your fork
59 | ```
60 | git clone git@github.com:YOUR_USERNAME_HERE/python-mander.git
61 | ```
62 | * Add the original repo as a remote
63 | ```
64 | git remote add upstream git@github.com:gerrymandr/python-mander.git
65 | ```
66 | * This project depends upon a C++ library sourced from a git submodule. Initialize and update the git submodule.
67 | ```
68 | git submodule init
69 | git submodule update
70 | ```
71 | * Optionally create and activate a [Python virtual environment](https://virtualenv.pypa.io/en/stable/).
72 | On Linux or Mac
73 | ```
74 | virtualenv env
75 | source env/bin/activate
76 | ```
77 | On Windows
78 | ```
79 | virtualenv env
80 | env\Scripts\activate
81 | ```
82 |
83 | On any platform, you may exit the virtual environment by running
84 | ```
85 | deactivate
86 | ```
87 | * Install the dependencies
88 | ```
89 | pip install -r requirements.txt
90 | ```
91 | * Build the project
92 | ```
93 | python setup.py build
94 | ```
95 | * If you need to specify a C compiler other than the default one on your system, you may add an inline environment variable `CC` and set it to the other compiler. For example, on a system with both gcc 4 and gcc 7 installed:
96 | ```
97 | CC=gcc-7 python setup.py build
98 | ```
99 |
100 |
101 | # Credits
102 |
103 | This package was created for the
104 | [Metric Geometry And Gerrymandering Group](https://sites.tufts.edu/gerrymandr/)
105 | as part of a hack-a-thon on August 10-11, 2017.
106 |
--------------------------------------------------------------------------------
/bin/mander:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import mander
4 | import sys
5 |
6 | if len(sys.argv)!=2:
7 | print("""Adds compactness scores to a shapefile
8 | Syntax: {0}
9 |
10 | - Filename of inputfile.
11 | """.format(sys.argv[0]))
12 | sys.exit(-1)
13 |
14 | mander.augmentShapefileWithScores(sys.argv[1])
15 |
--------------------------------------------------------------------------------
/conda.recipe/meta.yaml:
--------------------------------------------------------------------------------
1 | package:
2 | name: python-mander
3 | version: {{ GIT_DESCRIBE_TAG }}.{{ GIT_BUILD_STR }}
4 |
5 | source:
6 | git_url: ../
7 |
8 | build:
9 | script: python setup.py install --single-version-externally-managed --record=record.txt
10 |
11 | requirements:
12 | build:
13 | - {{ compiler('c') }}
14 | - {{ compiler('cxx') }}
15 | host:
16 | - python
17 | - setuptools
18 | run:
19 | - python
20 |
21 | test:
22 | imports:
23 | - mander
24 |
--------------------------------------------------------------------------------
/conda.recipe/run_test.py:
--------------------------------------------------------------------------------
1 | import mander
2 | mander.getListOfBoundedScores()
3 | mander.getListOfUnboundedScores()
4 |
--------------------------------------------------------------------------------
/examples/.ipynb_checkpoints/Untitled-checkpoint.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [],
3 | "metadata": {},
4 | "nbformat": 4,
5 | "nbformat_minor": 0
6 | }
7 |
--------------------------------------------------------------------------------
/lib/pybind11/attr.h:
--------------------------------------------------------------------------------
1 | /*
2 | pybind11/attr.h: Infrastructure for processing custom
3 | type and function attributes
4 |
5 | Copyright (c) 2016 Wenzel Jakob
6 |
7 | All rights reserved. Use of this source code is governed by a
8 | BSD-style license that can be found in the LICENSE file.
9 | */
10 |
11 | #pragma once
12 |
13 | #include "cast.h"
14 |
15 | NAMESPACE_BEGIN(pybind11)
16 |
17 | /// \addtogroup annotations
18 | /// @{
19 |
20 | /// Annotation for methods
21 | struct is_method { handle class_; is_method(const handle &c) : class_(c) { } };
22 |
23 | /// Annotation for operators
24 | struct is_operator { };
25 |
26 | /// Annotation for parent scope
27 | struct scope { handle value; scope(const handle &s) : value(s) { } };
28 |
29 | /// Annotation for documentation
30 | struct doc { const char *value; doc(const char *value) : value(value) { } };
31 |
32 | /// Annotation for function names
33 | struct name { const char *value; name(const char *value) : value(value) { } };
34 |
35 | /// Annotation indicating that a function is an overload associated with a given "sibling"
36 | struct sibling { handle value; sibling(const handle &value) : value(value.ptr()) { } };
37 |
38 | /// Annotation indicating that a class derives from another given type
39 | template struct base {
40 | PYBIND11_DEPRECATED("base() was deprecated in favor of specifying 'T' as a template argument to class_")
41 | base() { }
42 | };
43 |
44 | /// Keep patient alive while nurse lives
45 | template struct keep_alive { };
46 |
47 | /// Annotation indicating that a class is involved in a multiple inheritance relationship
48 | struct multiple_inheritance { };
49 |
50 | /// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class
51 | struct dynamic_attr { };
52 |
53 | /// Annotation which enables the buffer protocol for a type
54 | struct buffer_protocol { };
55 |
56 | /// Annotation which requests that a special metaclass is created for a type
57 | struct metaclass {
58 | handle value;
59 |
60 | PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.")
61 | metaclass() {}
62 |
63 | /// Override pybind11's default metaclass
64 | explicit metaclass(handle value) : value(value) { }
65 | };
66 |
67 | /// Annotation that marks a class as local to the module:
68 | struct module_local { const bool value; constexpr module_local(bool v = true) : value(v) { } };
69 |
70 | /// Annotation to mark enums as an arithmetic type
71 | struct arithmetic { };
72 |
73 | /** \rst
74 | A call policy which places one or more guard variables (``Ts...``) around the function call.
75 |
76 | For example, this definition:
77 |
78 | .. code-block:: cpp
79 |
80 | m.def("foo", foo, py::call_guard());
81 |
82 | is equivalent to the following pseudocode:
83 |
84 | .. code-block:: cpp
85 |
86 | m.def("foo", [](args...) {
87 | T scope_guard;
88 | return foo(args...); // forwarded arguments
89 | });
90 | \endrst */
91 | template struct call_guard;
92 |
93 | template <> struct call_guard<> { using type = detail::void_type; };
94 |
95 | template
96 | struct call_guard {
97 | static_assert(std::is_default_constructible::value,
98 | "The guard type must be default constructible");
99 |
100 | using type = T;
101 | };
102 |
103 | template
104 | struct call_guard {
105 | struct type {
106 | T guard{}; // Compose multiple guard types with left-to-right default-constructor order
107 | typename call_guard::type next{};
108 | };
109 | };
110 |
111 | /// @} annotations
112 |
113 | NAMESPACE_BEGIN(detail)
114 | /* Forward declarations */
115 | enum op_id : int;
116 | enum op_type : int;
117 | struct undefined_t;
118 | template struct op_;
119 | template struct init;
120 | template struct init_alias;
121 | inline void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret);
122 |
123 | /// Internal data structure which holds metadata about a keyword argument
124 | struct argument_record {
125 | const char *name; ///< Argument name
126 | const char *descr; ///< Human-readable version of the argument value
127 | handle value; ///< Associated Python object
128 | bool convert : 1; ///< True if the argument is allowed to convert when loading
129 | bool none : 1; ///< True if None is allowed when loading
130 |
131 | argument_record(const char *name, const char *descr, handle value, bool convert, bool none)
132 | : name(name), descr(descr), value(value), convert(convert), none(none) { }
133 | };
134 |
135 | /// Internal data structure which holds metadata about a bound function (signature, overloads, etc.)
136 | struct function_record {
137 | function_record()
138 | : is_constructor(false), is_stateless(false), is_operator(false),
139 | has_args(false), has_kwargs(false), is_method(false) { }
140 |
141 | /// Function name
142 | char *name = nullptr; /* why no C++ strings? They generate heavier code.. */
143 |
144 | // User-specified documentation string
145 | char *doc = nullptr;
146 |
147 | /// Human-readable version of the function signature
148 | char *signature = nullptr;
149 |
150 | /// List of registered keyword arguments
151 | std::vector args;
152 |
153 | /// Pointer to lambda function which converts arguments and performs the actual call
154 | handle (*impl) (function_call &) = nullptr;
155 |
156 | /// Storage for the wrapped function pointer and captured data, if any
157 | void *data[3] = { };
158 |
159 | /// Pointer to custom destructor for 'data' (if needed)
160 | void (*free_data) (function_record *ptr) = nullptr;
161 |
162 | /// Return value policy associated with this function
163 | return_value_policy policy = return_value_policy::automatic;
164 |
165 | /// True if name == '__init__'
166 | bool is_constructor : 1;
167 |
168 | /// True if this is a stateless function pointer
169 | bool is_stateless : 1;
170 |
171 | /// True if this is an operator (__add__), etc.
172 | bool is_operator : 1;
173 |
174 | /// True if the function has a '*args' argument
175 | bool has_args : 1;
176 |
177 | /// True if the function has a '**kwargs' argument
178 | bool has_kwargs : 1;
179 |
180 | /// True if this is a method
181 | bool is_method : 1;
182 |
183 | /// Number of arguments (including py::args and/or py::kwargs, if present)
184 | std::uint16_t nargs;
185 |
186 | /// Python method object
187 | PyMethodDef *def = nullptr;
188 |
189 | /// Python handle to the parent scope (a class or a module)
190 | handle scope;
191 |
192 | /// Python handle to the sibling function representing an overload chain
193 | handle sibling;
194 |
195 | /// Pointer to next overload
196 | function_record *next = nullptr;
197 | };
198 |
199 | /// Special data structure which (temporarily) holds metadata about a bound class
200 | struct type_record {
201 | PYBIND11_NOINLINE type_record()
202 | : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), module_local(false) { }
203 |
204 | /// Handle to the parent scope
205 | handle scope;
206 |
207 | /// Name of the class
208 | const char *name = nullptr;
209 |
210 | // Pointer to RTTI type_info data structure
211 | const std::type_info *type = nullptr;
212 |
213 | /// How large is the underlying C++ type?
214 | size_t type_size = 0;
215 |
216 | /// How large is the type's holder?
217 | size_t holder_size = 0;
218 |
219 | /// The global operator new can be overridden with a class-specific variant
220 | void *(*operator_new)(size_t) = ::operator new;
221 |
222 | /// Function pointer to class_<..>::init_instance
223 | void (*init_instance)(instance *, const void *) = nullptr;
224 |
225 | /// Function pointer to class_<..>::dealloc
226 | void (*dealloc)(const detail::value_and_holder &) = nullptr;
227 |
228 | /// List of base classes of the newly created type
229 | list bases;
230 |
231 | /// Optional docstring
232 | const char *doc = nullptr;
233 |
234 | /// Custom metaclass (optional)
235 | handle metaclass;
236 |
237 | /// Multiple inheritance marker
238 | bool multiple_inheritance : 1;
239 |
240 | /// Does the class manage a __dict__?
241 | bool dynamic_attr : 1;
242 |
243 | /// Does the class implement the buffer protocol?
244 | bool buffer_protocol : 1;
245 |
246 | /// Is the default (unique_ptr) holder type used?
247 | bool default_holder : 1;
248 |
249 | /// Is the class definition local to the module shared object?
250 | bool module_local : 1;
251 |
252 | PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) {
253 | auto base_info = detail::get_type_info(base, false);
254 | if (!base_info) {
255 | std::string tname(base.name());
256 | detail::clean_type_id(tname);
257 | pybind11_fail("generic_type: type \"" + std::string(name) +
258 | "\" referenced unknown base type \"" + tname + "\"");
259 | }
260 |
261 | if (default_holder != base_info->default_holder) {
262 | std::string tname(base.name());
263 | detail::clean_type_id(tname);
264 | pybind11_fail("generic_type: type \"" + std::string(name) + "\" " +
265 | (default_holder ? "does not have" : "has") +
266 | " a non-default holder type while its base \"" + tname + "\" " +
267 | (base_info->default_holder ? "does not" : "does"));
268 | }
269 |
270 | bases.append((PyObject *) base_info->type);
271 |
272 | if (base_info->type->tp_dictoffset != 0)
273 | dynamic_attr = true;
274 |
275 | if (caster)
276 | base_info->implicit_casts.emplace_back(type, caster);
277 | }
278 | };
279 |
280 | inline function_call::function_call(function_record &f, handle p) :
281 | func(f), parent(p) {
282 | args.reserve(f.nargs);
283 | args_convert.reserve(f.nargs);
284 | }
285 |
286 | /**
287 | * Partial template specializations to process custom attributes provided to
288 | * cpp_function_ and class_. These are either used to initialize the respective
289 | * fields in the type_record and function_record data structures or executed at
290 | * runtime to deal with custom call policies (e.g. keep_alive).
291 | */
292 | template struct process_attribute;
293 |
294 | template struct process_attribute_default {
295 | /// Default implementation: do nothing
296 | static void init(const T &, function_record *) { }
297 | static void init(const T &, type_record *) { }
298 | static void precall(function_call &) { }
299 | static void postcall(function_call &, handle) { }
300 | };
301 |
302 | /// Process an attribute specifying the function's name
303 | template <> struct process_attribute : process_attribute_default {
304 | static void init(const name &n, function_record *r) { r->name = const_cast(n.value); }
305 | };
306 |
307 | /// Process an attribute specifying the function's docstring
308 | template <> struct process_attribute : process_attribute_default {
309 | static void init(const doc &n, function_record *r) { r->doc = const_cast(n.value); }
310 | };
311 |
312 | /// Process an attribute specifying the function's docstring (provided as a C-style string)
313 | template <> struct process_attribute : process_attribute_default {
314 | static void init(const char *d, function_record *r) { r->doc = const_cast(d); }
315 | static void init(const char *d, type_record *r) { r->doc = const_cast(d); }
316 | };
317 | template <> struct process_attribute : process_attribute { };
318 |
319 | /// Process an attribute indicating the function's return value policy
320 | template <> struct process_attribute : process_attribute_default {
321 | static void init(const return_value_policy &p, function_record *r) { r->policy = p; }
322 | };
323 |
324 | /// Process an attribute which indicates that this is an overloaded function associated with a given sibling
325 | template <> struct process_attribute : process_attribute_default {
326 | static void init(const sibling &s, function_record *r) { r->sibling = s.value; }
327 | };
328 |
329 | /// Process an attribute which indicates that this function is a method
330 | template <> struct process_attribute : process_attribute_default {
331 | static void init(const is_method &s, function_record *r) { r->is_method = true; r->scope = s.class_; }
332 | };
333 |
334 | /// Process an attribute which indicates the parent scope of a method
335 | template <> struct process_attribute : process_attribute_default {
336 | static void init(const scope &s, function_record *r) { r->scope = s.value; }
337 | };
338 |
339 | /// Process an attribute which indicates that this function is an operator
340 | template <> struct process_attribute : process_attribute_default {
341 | static void init(const is_operator &, function_record *r) { r->is_operator = true; }
342 | };
343 |
344 | /// Process a keyword argument attribute (*without* a default value)
345 | template <> struct process_attribute : process_attribute_default {
346 | static void init(const arg &a, function_record *r) {
347 | if (r->is_method && r->args.empty())
348 | r->args.emplace_back("self", nullptr, handle(), true /*convert*/, false /*none not allowed*/);
349 | r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none);
350 | }
351 | };
352 |
353 | /// Process a keyword argument attribute (*with* a default value)
354 | template <> struct process_attribute : process_attribute_default {
355 | static void init(const arg_v &a, function_record *r) {
356 | if (r->is_method && r->args.empty())
357 | r->args.emplace_back("self", nullptr /*descr*/, handle() /*parent*/, true /*convert*/, false /*none not allowed*/);
358 |
359 | if (!a.value) {
360 | #if !defined(NDEBUG)
361 | std::string descr("'");
362 | if (a.name) descr += std::string(a.name) + ": ";
363 | descr += a.type + "'";
364 | if (r->is_method) {
365 | if (r->name)
366 | descr += " in method '" + (std::string) str(r->scope) + "." + (std::string) r->name + "'";
367 | else
368 | descr += " in method of '" + (std::string) str(r->scope) + "'";
369 | } else if (r->name) {
370 | descr += " in function '" + (std::string) r->name + "'";
371 | }
372 | pybind11_fail("arg(): could not convert default argument "
373 | + descr + " into a Python object (type not registered yet?)");
374 | #else
375 | pybind11_fail("arg(): could not convert default argument "
376 | "into a Python object (type not registered yet?). "
377 | "Compile in debug mode for more information.");
378 | #endif
379 | }
380 | r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none);
381 | }
382 | };
383 |
384 | /// Process a parent class attribute. Single inheritance only (class_ itself already guarantees that)
385 | template
386 | struct process_attribute::value>> : process_attribute_default {
387 | static void init(const handle &h, type_record *r) { r->bases.append(h); }
388 | };
389 |
390 | /// Process a parent class attribute (deprecated, does not support multiple inheritance)
391 | template
392 | struct process_attribute> : process_attribute_default> {
393 | static void init(const base &, type_record *r) { r->add_base(typeid(T), nullptr); }
394 | };
395 |
396 | /// Process a multiple inheritance attribute
397 | template <>
398 | struct process_attribute : process_attribute_default {
399 | static void init(const multiple_inheritance &, type_record *r) { r->multiple_inheritance = true; }
400 | };
401 |
402 | template <>
403 | struct process_attribute : process_attribute_default {
404 | static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; }
405 | };
406 |
407 | template <>
408 | struct process_attribute : process_attribute_default {
409 | static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; }
410 | };
411 |
412 | template <>
413 | struct process_attribute : process_attribute_default {
414 | static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; }
415 | };
416 |
417 | template <>
418 | struct process_attribute : process_attribute_default {
419 | static void init(const module_local &l, type_record *r) { r->module_local = l.value; }
420 | };
421 |
422 | /// Process an 'arithmetic' attribute for enums (does nothing here)
423 | template <>
424 | struct process_attribute : process_attribute_default {};
425 |
426 | template
427 | struct process_attribute> : process_attribute_default> { };
428 |
429 | /**
430 | * Process a keep_alive call policy -- invokes keep_alive_impl during the
431 | * pre-call handler if both Nurse, Patient != 0 and use the post-call handler
432 | * otherwise
433 | */
434 | template struct process_attribute> : public process_attribute_default> {
435 | template = 0>
436 | static void precall(function_call &call) { keep_alive_impl(Nurse, Patient, call, handle()); }
437 | template = 0>
438 | static void postcall(function_call &, handle) { }
439 | template = 0>
440 | static void precall(function_call &) { }
441 | template = 0>
442 | static void postcall(function_call &call, handle ret) { keep_alive_impl(Nurse, Patient, call, ret); }
443 | };
444 |
445 | /// Recursively iterate over variadic template arguments
446 | template struct process_attributes {
447 | static void init(const Args&... args, function_record *r) {
448 | int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... };
449 | ignore_unused(unused);
450 | }
451 | static void init(const Args&... args, type_record *r) {
452 | int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... };
453 | ignore_unused(unused);
454 | }
455 | static void precall(function_call &call) {
456 | int unused[] = { 0, (process_attribute::type>::precall(call), 0) ... };
457 | ignore_unused(unused);
458 | }
459 | static void postcall(function_call &call, handle fn_ret) {
460 | int unused[] = { 0, (process_attribute::type>::postcall(call, fn_ret), 0) ... };
461 | ignore_unused(unused);
462 | }
463 | };
464 |
465 | template
466 | using is_call_guard = is_instantiation;
467 |
468 | /// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found)
469 | template
470 | using extract_guard_t = typename exactly_one_t, Extra...>::type;
471 |
472 | /// Check the number of named arguments at compile time
473 | template ::value...),
475 | size_t self = constexpr_sum(std::is_same::value...)>
476 | constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) {
477 | return named == 0 || (self + named + has_args + has_kwargs) == nargs;
478 | }
479 |
480 | NAMESPACE_END(detail)
481 | NAMESPACE_END(pybind11)
482 |
--------------------------------------------------------------------------------
/lib/pybind11/buffer_info.h:
--------------------------------------------------------------------------------
1 | /*
2 | pybind11/buffer_info.h: Python buffer object interface
3 |
4 | Copyright (c) 2016 Wenzel Jakob
5 |
6 | All rights reserved. Use of this source code is governed by a
7 | BSD-style license that can be found in the LICENSE file.
8 | */
9 |
10 | #pragma once
11 |
12 | #include "common.h"
13 |
14 | NAMESPACE_BEGIN(pybind11)
15 |
16 | /// Information record describing a Python buffer object
17 | struct buffer_info {
18 | void *ptr = nullptr; // Pointer to the underlying storage
19 | ssize_t itemsize = 0; // Size of individual items in bytes
20 | ssize_t size = 0; // Total number of entries
21 | std::string format; // For homogeneous buffers, this should be set to format_descriptor::format()
22 | ssize_t ndim = 0; // Number of dimensions
23 | std::vector shape; // Shape of the tensor (1 entry per dimension)
24 | std::vector strides; // Number of entries between adjacent entries (for each per dimension)
25 |
26 | buffer_info() { }
27 |
28 | buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim,
29 | detail::any_container shape_in, detail::any_container strides_in)
30 | : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim),
31 | shape(std::move(shape_in)), strides(std::move(strides_in)) {
32 | if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size())
33 | pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length");
34 | for (size_t i = 0; i < (size_t) ndim; ++i)
35 | size *= shape[i];
36 | }
37 |
38 | template
39 | buffer_info(T *ptr, detail::any_container shape_in, detail::any_container strides_in)
40 | : buffer_info(private_ctr_tag(), ptr, sizeof(T), format_descriptor::format(), static_cast(shape_in->size()), std::move(shape_in), std::move(strides_in)) { }
41 |
42 | buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t size)
43 | : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}) { }
44 |
45 | template
46 | buffer_info(T *ptr, ssize_t size)
47 | : buffer_info(ptr, sizeof(T), format_descriptor::format(), size) { }
48 |
49 | explicit buffer_info(Py_buffer *view, bool ownview = true)
50 | : buffer_info(view->buf, view->itemsize, view->format, view->ndim,
51 | {view->shape, view->shape + view->ndim}, {view->strides, view->strides + view->ndim}) {
52 | this->view = view;
53 | this->ownview = ownview;
54 | }
55 |
56 | buffer_info(const buffer_info &) = delete;
57 | buffer_info& operator=(const buffer_info &) = delete;
58 |
59 | buffer_info(buffer_info &&other) {
60 | (*this) = std::move(other);
61 | }
62 |
63 | buffer_info& operator=(buffer_info &&rhs) {
64 | ptr = rhs.ptr;
65 | itemsize = rhs.itemsize;
66 | size = rhs.size;
67 | format = std::move(rhs.format);
68 | ndim = rhs.ndim;
69 | shape = std::move(rhs.shape);
70 | strides = std::move(rhs.strides);
71 | std::swap(view, rhs.view);
72 | std::swap(ownview, rhs.ownview);
73 | return *this;
74 | }
75 |
76 | ~buffer_info() {
77 | if (view && ownview) { PyBuffer_Release(view); delete view; }
78 | }
79 |
80 | private:
81 | struct private_ctr_tag { };
82 |
83 | buffer_info(private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim,
84 | detail::any_container &&shape_in, detail::any_container &&strides_in)
85 | : buffer_info(ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in)) { }
86 |
87 | Py_buffer *view = nullptr;
88 | bool ownview = false;
89 | };
90 |
91 | NAMESPACE_BEGIN(detail)
92 |
93 | template struct compare_buffer_info {
94 | static bool compare(const buffer_info& b) {
95 | return b.format == format_descriptor::format() && b.itemsize == (ssize_t) sizeof(T);
96 | }
97 | };
98 |
99 | template struct compare_buffer_info::value>> {
100 | static bool compare(const buffer_info& b) {
101 | return (size_t) b.itemsize == sizeof(T) && (b.format == format_descriptor::value ||
102 | ((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned::value ? "L" : "l")) ||
103 | ((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned::value ? "N" : "n")));
104 | }
105 | };
106 |
107 | NAMESPACE_END(detail)
108 | NAMESPACE_END(pybind11)
109 |
--------------------------------------------------------------------------------
/lib/pybind11/chrono.h:
--------------------------------------------------------------------------------
1 | /*
2 | pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime
3 |
4 | Copyright (c) 2016 Trent Houliston and
5 | Wenzel Jakob
6 |
7 | All rights reserved. Use of this source code is governed by a
8 | BSD-style license that can be found in the LICENSE file.
9 | */
10 |
11 | #pragma once
12 |
13 | #include "pybind11.h"
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | // Backport the PyDateTime_DELTA functions from Python3.3 if required
20 | #ifndef PyDateTime_DELTA_GET_DAYS
21 | #define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days)
22 | #endif
23 | #ifndef PyDateTime_DELTA_GET_SECONDS
24 | #define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds)
25 | #endif
26 | #ifndef PyDateTime_DELTA_GET_MICROSECONDS
27 | #define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta*)o)->microseconds)
28 | #endif
29 |
30 | NAMESPACE_BEGIN(pybind11)
31 | NAMESPACE_BEGIN(detail)
32 |
33 | template class duration_caster {
34 | public:
35 | typedef typename type::rep rep;
36 | typedef typename type::period period;
37 |
38 | typedef std::chrono::duration> days;
39 |
40 | bool load(handle src, bool) {
41 | using namespace std::chrono;
42 |
43 | // Lazy initialise the PyDateTime import
44 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; }
45 |
46 | if (!src) return false;
47 | // If invoked with datetime.delta object
48 | if (PyDelta_Check(src.ptr())) {
49 | value = type(duration_cast>(
50 | days(PyDateTime_DELTA_GET_DAYS(src.ptr()))
51 | + seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr()))
52 | + microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr()))));
53 | return true;
54 | }
55 | // If invoked with a float we assume it is seconds and convert
56 | else if (PyFloat_Check(src.ptr())) {
57 | value = type(duration_cast>(duration(PyFloat_AsDouble(src.ptr()))));
58 | return true;
59 | }
60 | else return false;
61 | }
62 |
63 | // If this is a duration just return it back
64 | static const std::chrono::duration& get_duration(const std::chrono::duration &src) {
65 | return src;
66 | }
67 |
68 | // If this is a time_point get the time_since_epoch
69 | template static std::chrono::duration get_duration(const std::chrono::time_point> &src) {
70 | return src.time_since_epoch();
71 | }
72 |
73 | static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) {
74 | using namespace std::chrono;
75 |
76 | // Use overloaded function to get our duration from our source
77 | // Works out if it is a duration or time_point and get the duration
78 | auto d = get_duration(src);
79 |
80 | // Lazy initialise the PyDateTime import
81 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; }
82 |
83 | // Declare these special duration types so the conversions happen with the correct primitive types (int)
84 | using dd_t = duration>;
85 | using ss_t = duration>;
86 | using us_t = duration;
87 |
88 | auto dd = duration_cast(d);
89 | auto subd = d - dd;
90 | auto ss = duration_cast(subd);
91 | auto us = duration_cast(subd - ss);
92 | return PyDelta_FromDSU(dd.count(), ss.count(), us.count());
93 | }
94 |
95 | PYBIND11_TYPE_CASTER(type, _("datetime.timedelta"));
96 | };
97 |
98 | // This is for casting times on the system clock into datetime.datetime instances
99 | template class type_caster> {
100 | public:
101 | typedef std::chrono::time_point type;
102 | bool load(handle src, bool) {
103 | using namespace std::chrono;
104 |
105 | // Lazy initialise the PyDateTime import
106 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; }
107 |
108 | if (!src) return false;
109 | if (PyDateTime_Check(src.ptr())) {
110 | std::tm cal;
111 | cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr());
112 | cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr());
113 | cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr());
114 | cal.tm_mday = PyDateTime_GET_DAY(src.ptr());
115 | cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1;
116 | cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900;
117 | cal.tm_isdst = -1;
118 |
119 | value = system_clock::from_time_t(std::mktime(&cal)) + microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr()));
120 | return true;
121 | }
122 | else return false;
123 | }
124 |
125 | static handle cast(const std::chrono::time_point &src, return_value_policy /* policy */, handle /* parent */) {
126 | using namespace std::chrono;
127 |
128 | // Lazy initialise the PyDateTime import
129 | if (!PyDateTimeAPI) { PyDateTime_IMPORT; }
130 |
131 | std::time_t tt = system_clock::to_time_t(src);
132 | // this function uses static memory so it's best to copy it out asap just in case
133 | // otherwise other code that is using localtime may break this (not just python code)
134 | std::tm localtime = *std::localtime(&tt);
135 |
136 | // Declare these special duration types so the conversions happen with the correct primitive types (int)
137 | using us_t = duration;
138 |
139 | return PyDateTime_FromDateAndTime(localtime.tm_year + 1900,
140 | localtime.tm_mon + 1,
141 | localtime.tm_mday,
142 | localtime.tm_hour,
143 | localtime.tm_min,
144 | localtime.tm_sec,
145 | (duration_cast(src.time_since_epoch() % seconds(1))).count());
146 | }
147 | PYBIND11_TYPE_CASTER(type, _("datetime.datetime"));
148 | };
149 |
150 | // Other clocks that are not the system clock are not measured as datetime.datetime objects
151 | // since they are not measured on calendar time. So instead we just make them timedeltas
152 | // Or if they have passed us a time as a float we convert that
153 | template class type_caster>
154 | : public duration_caster> {
155 | };
156 |
157 | template class type_caster>
158 | : public duration_caster> {
159 | };
160 |
161 | NAMESPACE_END(detail)
162 | NAMESPACE_END(pybind11)
163 |
--------------------------------------------------------------------------------
/lib/pybind11/class_support.h:
--------------------------------------------------------------------------------
1 | /*
2 | pybind11/class_support.h: Python C API implementation details for py::class_
3 |
4 | Copyright (c) 2017 Wenzel Jakob
5 |
6 | All rights reserved. Use of this source code is governed by a
7 | BSD-style license that can be found in the LICENSE file.
8 | */
9 |
10 | #pragma once
11 |
12 | #include "attr.h"
13 |
14 | NAMESPACE_BEGIN(pybind11)
15 | NAMESPACE_BEGIN(detail)
16 |
17 | inline PyTypeObject *type_incref(PyTypeObject *type) {
18 | Py_INCREF(type);
19 | return type;
20 | }
21 |
22 | #if !defined(PYPY_VERSION)
23 |
24 | /// `pybind11_static_property.__get__()`: Always pass the class instead of the instance.
25 | extern "C" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) {
26 | return PyProperty_Type.tp_descr_get(self, cls, cls);
27 | }
28 |
29 | /// `pybind11_static_property.__set__()`: Just like the above `__get__()`.
30 | extern "C" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) {
31 | PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj);
32 | return PyProperty_Type.tp_descr_set(self, cls, value);
33 | }
34 |
35 | /** A `static_property` is the same as a `property` but the `__get__()` and `__set__()`
36 | methods are modified to always use the object type instead of a concrete instance.
37 | Return value: New reference. */
38 | inline PyTypeObject *make_static_property_type() {
39 | constexpr auto *name = "pybind11_static_property";
40 | auto name_obj = reinterpret_steal