pax_global_header 0000666 0000000 0000000 00000000064 12262777333 0014526 g ustar 00root root 0000000 0000000 52 comment=1a32e6934315c50f67a4452d033888a9c4a6f7d8
instant-1.3.0/ 0000775 0000000 0000000 00000000000 12262777333 0013207 5 ustar 00root root 0000000 0000000 instant-1.3.0/.bzrignore 0000664 0000000 0000000 00000000020 12262777333 0015201 0 ustar 00root root 0000000 0000000 build
tests/**/
instant-1.3.0/.gitignore 0000664 0000000 0000000 00000000021 12262777333 0015170 0 ustar 00root root 0000000 0000000 build/
tests/**/
instant-1.3.0/AUTHORS 0000664 0000000 0000000 00000000352 12262777333 0014257 0 ustar 00root root 0000000 0000000 Main authors:
Martin Alnæs (martinal@simula.no)
Kent-Andre Mardal (kent-and@simula.no)
Magne Westlie (magnew@simula.no)
Ilmar Wilbers (ilmarw@simula.no)
Suggestions, bugfixes etc:
Johan Hake
Anders Logg
Johannes Ring
Ola Skavhaug instant-1.3.0/COPYING 0000664 0000000 0000000 00000003327 12262777333 0014247 0 ustar 00root root 0000000 0000000 Copyright (c) 2006-2009, Magne Westlie, Kent-Andre Mardal, Martin Alnæs, and
Ilmar Wilbers, Simula Research Laboratory. All rights reserved.
Instant is licensed under either the GNU LGPL Version 2.1, see
http://www.gnu.org or the so-called BSD license which is the following:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Simula Research Laboratory nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
instant-1.3.0/ChangeLog 0000664 0000000 0000000 00000004277 12262777333 0014773 0 ustar 00root root 0000000 0000000 1.3.0 [2014-01-07]
- Add file_lock which can be used within a with statement
- Introduce set_log_level and deprecate set_logging_level
1.2.0 [2013-03-24]
- Allow to use CMake instead of distutils/pkg-config
1.1.0 [2013-01-07]
- Converting python2 syntax to python3 (run 2to3)
- Patch to make instant work with python2
- Cache dir is now created if not existing
1.0.0 [2011-12-07]
- Copy all files to ~/.instant/error/module_name when Instant fails
- If environmental variable INSTANT_DISPLAY_COMPILE_LOG is set the content
of compile.log will be displayed
- Removed copying of compile.log to ~/.instant/error/
1.0-beta2 [2011-10-28]
- Added support for flufl.lock for NFS safe file locking
1.0-beta [2011-08-11]
- Error log is now copied to ~/.instant/error/module_name/compile.log
and ~/.instant/error/compile.log for easier retrieval
0.9.10 [2011-05-16]
- Added support for setting swig binary and swig path
0.9.9 [2011-02-23]
- Optimizations
- Added support for VTK and VMTK
0.9.8 [2010-02-15]
- Fix cache related memory leak
0.9.7
- Use typemaps from the NumPy SWIG interface file (numpy.i)
enabling the use of many new data types.
- Removed support for Numeric and numarray.
0.9.6
- Minor update with some new utility functions required by FFC.
0.9.5
- Restructured and rewritten much of the code.
- Improved multilevel cache functionality.
- Added instant-clean and instant-showcache scripts.
0.9.4
- Various new examples with swiginac and sympy implemented.
- Bug fix on 64bit. Removed director flag by default.
0.9.3
- Implemented caching
0.9.2
- Bug fix for the JIT in FFC
0.9.1
- Added test example which demonstrate use of external C code.
- Added flag to turn of regeneration of the interface file
(useful during debugging)
0.9
- Port to Windows with mingw by laserjungle, some updates
by Martin Alnæs, and some cleanup.
0.8
- Added support for NumPy and Numarray.
0.7
- Added functionality for the use of pkg-config files.
0.6
- Created a more user-friendly interface
0.5
- Added SWIG directors for cross language inheritance
0.4
- Added md5sum to avoid unnecessary compilation
0.3
- Support for NumPy arrays
0.2
- Fixed bug in setup script
0.1
- Initial release of Instant
instant-1.3.0/README 0000664 0000000 0000000 00000000740 12262777333 0014070 0 ustar 00root root 0000000 0000000 =======
Instant
=======
Instant is a Python module that allows for instant inlining of C and
C++ code in Python. It is a small Python module built on top of SWIG
and Distutils. For more information, visit:
https://bitbucket.org/fenics-project/instant
Dependencies
============
Instant depends on Python 2.5 or later, SWIG, and NumPy
Optional dependencies
=====================
To enable NFS safe file locking flufl.lock can be installed:
https://launchpad.net/flufl.lock
instant-1.3.0/TODO 0000664 0000000 0000000 00000001356 12262777333 0013704 0 ustar 00root root 0000000 0000000 TODO:
- Print error when tmp directory can't be deleted (in instant-clean).
Maybe add username to tmp dir name suffix?
/tmp on cluster contains instant directories
of many users.
- Keep a most recently used list
add a max cache size option to ~/.instant/intantrc
clean up the oldest modules whenever we exceed this quota
- Add argument to provide a cache subfolder name.
Then instant-clean can take an argument to clean only the "ffc" cache subfolder etc.
- Does instant handle full disk properly? (Does any software? Define properly!)
- Fix arguments not used in setup.py
- Use object files argument.
- Improve documentation
- Add tests for all variants of cache mechanisms available now
- Clean up imports, don't use import *
instant-1.3.0/doc/ 0000775 0000000 0000000 00000000000 12262777333 0013754 5 ustar 00root root 0000000 0000000 instant-1.3.0/doc/Instant.html 0000664 0000000 0000000 00000010253 12262777333 0016263 0 ustar 00root root 0000000 0000000
Release 0.9 (3/01/07): Port to Windows with mingw pluss some
added functionality and clean up.
Release 0.8 (5/10/06): Added support for NumPy
and Numarray.
Release 0.7 (12/09/06): Added functionality for the use of pkg-config files. Release 0.6 (17/07/06): Cleanup of the user interface. Release 0.5 (10/03/06): Instant uses SWIG directors for cross language inheritance. Release 0.4 (03/01/05): Added md5sums to avoid unnecessary compilation. Release 0.3 (27/11/05): Instant supports Numeric arrays.
Appetizer
Instant is a Python module that allows for instant inlining of C and
C++ code in Python. It is a small Python module built on top of SWIG and Distutils.
Example of use:
from Instant import inline
add_func = inline("double add(double a, double b){ return a+b; }")
print "The sum of 3 and 4.5 is ", add_func(3, 4.5)
Example with NumPy arrays converted to C double arrays:
from Instant import inline_with_numpy
c_code = """
double sum (int n1, double* array1){
double tmp = 0.0;
for (int i=0; i<n1; i++) {
tmp += array1[i];
}
return tmp;
}
"""
sum_func = inline_with_numpy(c_code, arrays = [['n1', 'array1']])
a = numpy.arange(10000000); a = numpy.sin(a)
sum1 = sum_func(a)
On my machine, the above example is about twice as fast as using the
sum function implemented in NumPy. This comparison
is of course not fair, since there are no safety checks in the
above example. The comparison is implemented in the file test9.py
that comes with the Instant package. The old package Numeric is about
as slow as NumPy (test2.py), while the same example with Numarray is
about as fast as with Instant (test10.py).
Requirement
Instant requires Python and SWIG. It has only been tested with
Python 2.3 and 2.4 and SWIG 1.3.24 or newer. It only runs on Unix systems.
logging.Filter:
Filter instances are used to perform arbitrary filtering of
LogRecords.
logging.Filterer:
A base class for loggers and handlers which allows them to share
common code.
logging.Logger:
Instances of the Logger class represent a single logging
channel.
logging.RootLogger:
A root logger is not that different to any other logger, except
that it must have a logging level and there is only one instance of
it in the hierarchy.
logging.Handler:
Handler instances dispatch logging events to specific
destinations.
logging.StreamHandler:
A handler class which writes logging records, appropriately
formatted, to a stream.
logging.FileHandler:
A handler class which writes formatted logging records to disk
files.
logging.Formatter:
Formatter instances are used to convert a LogRecord to text.
logging.LogRecord:
A LogRecord instance represents an event being logged.
logging.Manager:
There is [under normal circumstances] just one Manager instance,
which holds the hierarchy of loggers.
logging.PlaceHolder:
PlaceHolder instances are used in the Manager logger hierarchy
to take the place of nodes for which no loggers have been
defined.
object:
The most base type
exceptions.BaseException:
Common base class for all exceptions
exceptions.Exception:
Common base class for all non-exit exceptions.
tempfile._RandomNameSequence:
An instance of _RandomNameSequence generates an endless sequence
of unpredictable strings which can safely be incorporated into file
names.
instant-1.3.0/doc/html_reference/crarr.png 0000664 0000000 0000000 00000000524 12262777333 0020556 0 ustar 00root root 0000000 0000000 PNG
IHDR
eE ,tEXtCreation Time Tue 22 Aug 2006 00:43:10 -0500`X tIME)} pHYs nu> gAMA a EPLTEðf4sW ЊrD`@ bCܖX{`,lNo@xdE螊dƴ~Twv tRNS @f MIDATxc`@0&+(;;/EXؑ?n b;'+Y# (r<" IENDB` instant-1.3.0/doc/html_reference/epydoc.css 0000664 0000000 0000000 00000037227 12262777333 0020746 0 ustar 00root root 0000000 0000000
/* Epydoc CSS Stylesheet
*
* This stylesheet can be used to customize the appearance of epydoc's
* HTML output.
*
*/
/* Default Colors & Styles
* - Set the default foreground & background color with 'body'; and
* link colors with 'a:link' and 'a:visited'.
* - Use bold for decision list terms.
* - The heading styles defined here are used for headings *within*
* docstring descriptions. All headings used by epydoc itself use
* either class='epydoc' or class='toc' (CSS styles for both
* defined below).
*/
body { background: #ffffff; color: #000000; }
p { margin-top: 0.5em; margin-bottom: 0.5em; }
a:link { color: #0000ff; }
a:visited { color: #204080; }
dt { font-weight: bold; }
h1 { font-size: +140%; font-style: italic;
font-weight: bold; }
h2 { font-size: +125%; font-style: italic;
font-weight: bold; }
h3 { font-size: +110%; font-style: italic;
font-weight: normal; }
code { font-size: 100%; }
/* N.B.: class, not pseudoclass */
a.link { font-family: monospace; }
/* Page Header & Footer
* - The standard page header consists of a navigation bar (with
* pointers to standard pages such as 'home' and 'trees'); a
* breadcrumbs list, which can be used to navigate to containing
* classes or modules; options links, to show/hide private
* variables and to show/hide frames; and a page title (using
*
). The page title may be followed by a link to the
* corresponding source code (using 'span.codelink').
* - The footer consists of a navigation bar, a timestamp, and a
* pointer to epydoc's homepage.
*/
h1.epydoc { margin: 0; font-size: +140%; font-weight: bold; }
h2.epydoc { font-size: +130%; font-weight: bold; }
h3.epydoc { font-size: +115%; font-weight: bold;
margin-top: 0.2em; }
td h3.epydoc { font-size: +115%; font-weight: bold;
margin-bottom: 0; }
table.navbar { background: #a0c0ff; color: #000000;
border: 2px groove #c0d0d0; }
table.navbar table { color: #000000; }
th.navbar-select { background: #70b0ff;
color: #000000; }
table.navbar a { text-decoration: none; }
table.navbar a:link { color: #0000ff; }
table.navbar a:visited { color: #204080; }
span.breadcrumbs { font-size: 85%; font-weight: bold; }
span.options { font-size: 70%; }
span.codelink { font-size: 85%; }
td.footer { font-size: 85%; }
/* Table Headers
* - Each summary table and details section begins with a 'header'
* row. This row contains a section title (marked by
* 'span.table-header') as well as a show/hide private link
* (marked by 'span.options', defined above).
* - Summary tables that contain user-defined groups mark those
* groups using 'group header' rows.
*/
td.table-header { background: #70b0ff; color: #000000;
border: 1px solid #608090; }
td.table-header table { color: #000000; }
td.table-header table a:link { color: #0000ff; }
td.table-header table a:visited { color: #204080; }
span.table-header { font-size: 120%; font-weight: bold; }
th.group-header { background: #c0e0f8; color: #000000;
text-align: left; font-style: italic;
font-size: 115%;
border: 1px solid #608090; }
/* Summary Tables (functions, variables, etc)
* - Each object is described by a single row of the table with
* two cells. The left cell gives the object's type, and is
* marked with 'code.summary-type'. The right cell gives the
* object's name and a summary description.
* - CSS styles for the table's header and group headers are
* defined above, under 'Table Headers'
*/
table.summary { border-collapse: collapse;
background: #e8f0f8; color: #000000;
border: 1px solid #608090;
margin-bottom: 0.5em; }
td.summary { border: 1px solid #608090; }
code.summary-type { font-size: 85%; }
table.summary a:link { color: #0000ff; }
table.summary a:visited { color: #204080; }
/* Details Tables (functions, variables, etc)
* - Each object is described in its own div.
* - A single-row summary table w/ table-header is used as
* a header for each details section (CSS style for table-header
* is defined above, under 'Table Headers').
*/
table.details { border-collapse: collapse;
background: #e8f0f8; color: #000000;
border: 1px solid #608090;
margin: .2em 0 0 0; }
table.details table { color: #000000; }
table.details a:link { color: #0000ff; }
table.details a:visited { color: #204080; }
/* Fields */
dl.fields { margin-left: 2em; margin-top: 1em;
margin-bottom: 1em; }
dl.fields dd ul { margin-left: 0em; padding-left: 0em; }
dl.fields dd ul li ul { margin-left: 2em; padding-left: 0em; }
div.fields { margin-left: 2em; }
div.fields p { margin-bottom: 0.5em; }
/* Index tables (identifier index, term index, etc)
* - link-index is used for indices containing lists of links
* (namely, the identifier index & term index).
* - index-where is used in link indices for the text indicating
* the container/source for each link.
* - metadata-index is used for indices containing metadata
* extracted from fields (namely, the bug index & todo index).
*/
table.link-index { border-collapse: collapse;
background: #e8f0f8; color: #000000;
border: 1px solid #608090; }
td.link-index { border-width: 0px; }
table.link-index a:link { color: #0000ff; }
table.link-index a:visited { color: #204080; }
span.index-where { font-size: 70%; }
table.metadata-index { border-collapse: collapse;
background: #e8f0f8; color: #000000;
border: 1px solid #608090;
margin: .2em 0 0 0; }
td.metadata-index { border-width: 1px; border-style: solid; }
table.metadata-index a:link { color: #0000ff; }
table.metadata-index a:visited { color: #204080; }
/* Function signatures
* - sig* is used for the signature in the details section.
* - .summary-sig* is used for the signature in the summary
* table, and when listing property accessor functions.
* */
.sig-name { color: #006080; }
.sig-arg { color: #008060; }
.sig-default { color: #602000; }
.summary-sig { font-family: monospace; }
.summary-sig-name { color: #006080; font-weight: bold; }
table.summary a.summary-sig-name:link
{ color: #006080; font-weight: bold; }
table.summary a.summary-sig-name:visited
{ color: #006080; font-weight: bold; }
.summary-sig-arg { color: #006040; }
.summary-sig-default { color: #501800; }
/* Subclass list
*/
ul.subclass-list { display: inline; }
ul.subclass-list li { display: inline; }
/* To render variables, classes etc. like functions */
table.summary .summary-name { color: #006080; font-weight: bold;
font-family: monospace; }
table.summary
a.summary-name:link { color: #006080; font-weight: bold;
font-family: monospace; }
table.summary
a.summary-name:visited { color: #006080; font-weight: bold;
font-family: monospace; }
/* Variable values
* - In the 'variable details' sections, each varaible's value is
* listed in a 'pre.variable' box. The width of this box is
* restricted to 80 chars; if the value's repr is longer than
* this it will be wrapped, using a backslash marked with
* class 'variable-linewrap'. If the value's repr is longer
* than 3 lines, the rest will be ellided; and an ellipsis
* marker ('...' marked with 'variable-ellipsis') will be used.
* - If the value is a string, its quote marks will be marked
* with 'variable-quote'.
* - If the variable is a regexp, it is syntax-highlighted using
* the re* CSS classes.
*/
pre.variable { padding: .5em; margin: 0;
background: #dce4ec; color: #000000;
border: 1px solid #708890; }
.variable-linewrap { color: #604000; font-weight: bold; }
.variable-ellipsis { color: #604000; font-weight: bold; }
.variable-quote { color: #604000; font-weight: bold; }
.variable-group { color: #008000; font-weight: bold; }
.variable-op { color: #604000; font-weight: bold; }
.variable-string { color: #006030; }
.variable-unknown { color: #a00000; font-weight: bold; }
.re { color: #000000; }
.re-char { color: #006030; }
.re-op { color: #600000; }
.re-group { color: #003060; }
.re-ref { color: #404040; }
/* Base tree
* - Used by class pages to display the base class hierarchy.
*/
pre.base-tree { font-size: 80%; margin: 0; }
/* Frames-based table of contents headers
* - Consists of two frames: one for selecting modules; and
* the other listing the contents of the selected module.
* - h1.toc is used for each frame's heading
* - h2.toc is used for subheadings within each frame.
*/
h1.toc { text-align: center; font-size: 105%;
margin: 0; font-weight: bold;
padding: 0; }
h2.toc { font-size: 100%; font-weight: bold;
margin: 0.5em 0 0 -0.3em; }
/* Syntax Highlighting for Source Code
* - doctest examples are displayed in a 'pre.py-doctest' block.
* If the example is in a details table entry, then it will use
* the colors specified by the 'table pre.py-doctest' line.
* - Source code listings are displayed in a 'pre.py-src' block.
* Each line is marked with 'span.py-line' (used to draw a line
* down the left margin, separating the code from the line
* numbers). Line numbers are displayed with 'span.py-lineno'.
* The expand/collapse block toggle button is displayed with
* 'a.py-toggle' (Note: the CSS style for 'a.py-toggle' should not
* modify the font size of the text.)
* - If a source code page is opened with an anchor, then the
* corresponding code block will be highlighted. The code
* block's header is highlighted with 'py-highlight-hdr'; and
* the code block's body is highlighted with 'py-highlight'.
* - The remaining py-* classes are used to perform syntax
* highlighting (py-string for string literals, py-name for names,
* etc.)
*/
pre.py-doctest { padding: .5em; margin: 1em;
background: #e8f0f8; color: #000000;
border: 1px solid #708890; }
table pre.py-doctest { background: #dce4ec;
color: #000000; }
pre.py-src { border: 2px solid #000000;
background: #f0f0f0; color: #000000; }
.py-line { border-left: 2px solid #000000;
margin-left: .2em; padding-left: .4em; }
.py-lineno { font-style: italic; font-size: 90%;
padding-left: .5em; }
a.py-toggle { text-decoration: none; }
div.py-highlight-hdr { border-top: 2px solid #000000;
border-bottom: 2px solid #000000;
background: #d8e8e8; }
div.py-highlight { border-bottom: 2px solid #000000;
background: #d0e0e0; }
.py-prompt { color: #005050; font-weight: bold;}
.py-more { color: #005050; font-weight: bold;}
.py-string { color: #006030; }
.py-comment { color: #003060; }
.py-keyword { color: #600000; }
.py-output { color: #404040; }
.py-name { color: #000050; }
.py-name:link { color: #000050 !important; }
.py-name:visited { color: #000050 !important; }
.py-number { color: #005000; }
.py-defname { color: #000060; font-weight: bold; }
.py-def-name { color: #000060; font-weight: bold; }
.py-base-class { color: #000060; }
.py-param { color: #000060; }
.py-docstring { color: #006030; }
.py-decorator { color: #804020; }
/* Use this if you don't want links to names underlined: */
/*a.py-name { text-decoration: none; }*/
/* Graphs & Diagrams
* - These CSS styles are used for graphs & diagrams generated using
* Graphviz dot. 'img.graph-without-title' is used for bare
* diagrams (to remove the border created by making the image
* clickable).
*/
img.graph-without-title { border: none; }
img.graph-with-title { border: 1px solid #000000; }
span.graph-title { font-weight: bold; }
span.graph-caption { }
/* General-purpose classes
* - 'p.indent-wrapped-lines' defines a paragraph whose first line
* is not indented, but whose subsequent lines are.
* - The 'nomargin-top' class is used to remove the top margin (e.g.
* from lists). The 'nomargin' class is used to remove both the
* top and bottom margin (but not the left or right margin --
* for lists, that would cause the bullets to disappear.)
*/
p.indent-wrapped-lines { padding: 0 0 0 7em; text-indent: -7em;
margin: 0; }
.nomargin-top { margin-top: 0; }
.nomargin { margin-top: 0; margin-bottom: 0; }
/* HTML Log */
div.log-block { padding: 0; margin: .5em 0 .5em 0;
background: #e8f0f8; color: #000000;
border: 1px solid #000000; }
div.log-error { padding: .1em .3em .1em .3em; margin: 4px;
background: #ffb0b0; color: #000000;
border: 1px solid #000000; }
div.log-warning { padding: .1em .3em .1em .3em; margin: 4px;
background: #ffffb0; color: #000000;
border: 1px solid #000000; }
div.log-info { padding: .1em .3em .1em .3em; margin: 4px;
background: #b0ffb0; color: #000000;
border: 1px solid #000000; }
h2.log-hdr { background: #70b0ff; color: #000000;
margin: 0; padding: 0em 0.5em 0em 0.5em;
border-bottom: 1px solid #000000; font-size: 110%; }
p.log { font-weight: bold; margin: .5em 0 .5em 0; }
tr.opt-changed { color: #000000; font-weight: bold; }
tr.opt-default { color: #606060; }
pre.log { margin: 0; padding: 0; padding-left: 1em; }
instant-1.3.0/doc/html_reference/epydoc.js 0000664 0000000 0000000 00000024525 12262777333 0020567 0 ustar 00root root 0000000 0000000 function toggle_private() {
// Search for any private/public links on this page. Store
// their old text in "cmd," so we will know what action to
// take; and change their text to the opposite action.
var cmd = "?";
var elts = document.getElementsByTagName("a");
for(var i=0; i";
s += " ";
for (var i=0; i... ";
elt.innerHTML = s;
}
}
function toggle(id) {
elt = document.getElementById(id+"-toggle");
if (elt.innerHTML == "-")
collapse(id);
else
expand(id);
return false;
}
function highlight(id) {
var elt = document.getElementById(id+"-def");
if (elt) elt.className = "py-highlight-hdr";
var elt = document.getElementById(id+"-expanded");
if (elt) elt.className = "py-highlight";
var elt = document.getElementById(id+"-collapsed");
if (elt) elt.className = "py-highlight";
}
function num_lines(s) {
var n = 1;
var pos = s.indexOf("\n");
while ( pos > 0) {
n += 1;
pos = s.indexOf("\n", pos+1);
}
return n;
}
// Collapse all blocks that mave more than `min_lines` lines.
function collapse_all(min_lines) {
var elts = document.getElementsByTagName("div");
for (var i=0; i 0)
if (elt.id.substring(split, elt.id.length) == "-expanded")
if (num_lines(elt.innerHTML) > min_lines)
collapse(elt.id.substring(0, split));
}
}
function expandto(href) {
var start = href.indexOf("#")+1;
if (start != 0 && start != href.length) {
if (href.substring(start, href.length) != "-") {
collapse_all(4);
pos = href.indexOf(".", start);
while (pos != -1) {
var id = href.substring(start, pos);
expand(id);
pos = href.indexOf(".", pos+1);
}
var id = href.substring(start, href.length);
expand(id);
highlight(id);
}
}
}
function kill_doclink(id) {
var parent = document.getElementById(id);
parent.removeChild(parent.childNodes.item(0));
}
function auto_kill_doclink(ev) {
if (!ev) var ev = window.event;
if (!this.contains(ev.toElement)) {
var parent = document.getElementById(this.parentID);
parent.removeChild(parent.childNodes.item(0));
}
}
function doclink(id, name, targets_id) {
var elt = document.getElementById(id);
// If we already opened the box, then destroy it.
// (This case should never occur, but leave it in just in case.)
if (elt.childNodes.length > 1) {
elt.removeChild(elt.childNodes.item(0));
}
else {
// The outer box: relative + inline positioning.
var box1 = document.createElement("div");
box1.style.position = "relative";
box1.style.display = "inline";
box1.style.top = 0;
box1.style.left = 0;
// A shadow for fun
var shadow = document.createElement("div");
shadow.style.position = "absolute";
shadow.style.left = "-1.3em";
shadow.style.top = "-1.3em";
shadow.style.background = "#404040";
// The inner box: absolute positioning.
var box2 = document.createElement("div");
box2.style.position = "relative";
box2.style.border = "1px solid #a0a0a0";
box2.style.left = "-.2em";
box2.style.top = "-.2em";
box2.style.background = "white";
box2.style.padding = ".3em .4em .3em .4em";
box2.style.fontStyle = "normal";
box2.onmouseout=auto_kill_doclink;
box2.parentID = id;
// Get the targets
var targets_elt = document.getElementById(targets_id);
var targets = targets_elt.getAttribute("targets");
var links = "";
target_list = targets.split(",");
for (var i=0; i" +
target[0] + "";
}
// Put it all together.
elt.insertBefore(box1, elt.childNodes.item(0));
//box1.appendChild(box2);
box1.appendChild(shadow);
shadow.appendChild(box2);
box2.innerHTML =
"Which "+name+" do you want to see documentation for?" +
"
";
}
return false;
}
function get_anchor() {
var href = location.href;
var start = href.indexOf("#")+1;
if ((start != 0) && (start != href.length))
return href.substring(start, href.length);
}
function redirect_url(dottedName) {
// Scan through each element of the "pages" list, and check
// if "name" matches with any of them.
for (var i=0; i-m" or "-c";
// extract the portion & compare it to dottedName.
var pagename = pages[i].substring(0, pages[i].length-2);
if (pagename == dottedName.substring(0,pagename.length)) {
// We've found a page that matches `dottedName`;
// construct its URL, using leftover `dottedName`
// content to form an anchor.
var pagetype = pages[i].charAt(pages[i].length-1);
var url = pagename + ((pagetype=="m")?"-module.html":
"-class.html");
if (dottedName.length > pagename.length)
url += "#" + dottedName.substring(pagename.length+1,
dottedName.length);
return url;
}
}
}
instant-1.3.0/doc/html_reference/frames.html 0000664 0000000 0000000 00000001115 12262777333 0021077 0 ustar 00root root 0000000 0000000
API Documentation
instant-1.3.0/doc/html_reference/help.html 0000664 0000000 0000000 00000026013 12262777333 0020556 0 ustar 00root root 0000000 0000000
Help
This document contains the API (Application Programming Interface)
documentation for this project. Documentation for the Python
objects defined by the project is divided into separate pages for each
package, module, and class. The API documentation also includes two
pages containing information about the project as a whole: a trees
page, and an index page.
Object Documentation
Each Package Documentation page contains:
A description of the package.
A list of the modules and sub-packages contained by the
package.
A summary of the classes defined by the package.
A summary of the functions defined by the package.
A summary of the variables defined by the package.
A detailed description of each function defined by the
package.
A detailed description of each variable defined by the
package.
Each Module Documentation page contains:
A description of the module.
A summary of the classes defined by the module.
A summary of the functions defined by the module.
A summary of the variables defined by the module.
A detailed description of each function defined by the
module.
A detailed description of each variable defined by the
module.
Each Class Documentation page contains:
A class inheritance diagram.
A list of known subclasses.
A description of the class.
A summary of the methods defined by the class.
A summary of the instance variables defined by the class.
A summary of the class (static) variables defined by the
class.
A detailed description of each method defined by the
class.
A detailed description of each instance variable defined by the
class.
A detailed description of each class (static) variable defined
by the class.
Project Documentation
The Trees page contains the module and class hierarchies:
The module hierarchy lists every package and module, with
modules grouped into packages. At the top level, and within each
package, modules and sub-packages are listed alphabetically.
The class hierarchy lists every class, grouped by base
class. If a class has more than one base class, then it will be
listed under each base class. At the top level, and under each base
class, classes are listed alphabetically.
The Index page contains indices of terms and
identifiers:
The term index lists every term indexed by any object's
documentation. For each term, the index provides links to each
place where the term is indexed.
The identifier index lists the (short) name of every package,
module, class, method, function, variable, and parameter. For each
identifier, the index provides a short description, and a link to
its documentation.
The Table of Contents
The table of contents occupies the two frames on the left side of
the window. The upper-left frame displays the project
contents, and the lower-left frame displays the module
contents:
Project Contents...
API Documentation Frame
Module Contents ...
The project contents frame contains a list of all packages
and modules that are defined by the project. Clicking on an entry
will display its contents in the module contents frame. Clicking on a
special entry, labeled "Everything," will display the contents of
the entire project.
The module contents frame contains a list of every
submodule, class, type, exception, function, and variable defined by a
module or package. Clicking on an entry will display its
documentation in the API documentation frame. Clicking on the name of
the module, at the top of the frame, will display the documentation
for the module itself.
The "frames" and "no frames" buttons below the top
navigation bar can be used to control whether the table of contents is
displayed or not.
The Navigation Bar
A navigation bar is located at the top and bottom of every page.
It indicates what type of page you are currently viewing, and allows
you to go to related pages. The following table describes the labels
on the navigation bar. Note that not some labels (such as
[Parent]) are not displayed on all pages.
Label
Highlighted when...
Links to...
[Parent]
(never highlighted)
the parent of the current package
[Package]
viewing a package
the package containing the current object
[Module]
viewing a module
the module containing the current object
[Class]
viewing a class
the class containing the current object
[Trees]
viewing the trees page
the trees page
[Index]
viewing the index page
the index page
[Help]
viewing the help page
the help page
The "show private" and "hide private" buttons below
the top navigation bar can be used to control whether documentation
for private objects is displayed. Private objects are usually defined
as objects whose (short) names begin with a single underscore, but do
not end with an underscore. For example, "_x",
"__pprint", and "epydoc.epytext._tokenize"
are private objects; but "re.sub",
"__init__", and "type_" are not. However,
if a module defines the "__all__" variable, then its
contents are used to decide which objects are private.
A timestamp below the bottom navigation bar indicates when each
page was last updated.
Instant allows compiled C/C++ modules to be created at runtime in your
Python application, using SWIG to wrap the C/C++ code.
A simple example:
>>> from instant import inline
>>> add_func = inline("double add(double a, double b){ return a+b; }")
>>> print"The sum of 3 and 4.5 is ", add_func(3, 4.5)
The main functions are build_module,
write_code, and inline* see their documentation
for more details.
For more examples, see the tests/ directory in the Instant
distribution.
Questions, bugs and patches should be sent to
instant-dev@fenics.org.
Version:
0.9.7
Date:
2009-05-28
Author:
Magne Westlie, Kent-Andre Mardal <kent-and@simula.no>, Martin
Alnes <martinal@simula.no>, Ilmar M. Wilbers
<ilmarw@simula.no>
1""" 2Instant allows compiled C/C++ modules to be created 3at runtime in your Python application, using SWIG to wrap the 4C/C++ code. 5 6A simple example: 7 >>> from instant import inline 8 >>> add_func = inline(\"double add(double a, double b){ return a+b; }\") 9 >>> print "The sum of 3 and 4.5 is ", add_func(3, 4.5)1011The main functions are C{build_module}, C{write_code}, and12C{inline*} see their documentation for more details.1314For more examples, see the tests/ directory in the Instant distribution.1516Questions, bugs and patches should be sent to instant-dev@fenics.org.17"""1819__authors__="Magne Westlie, Kent-Andre Mardal <kent-and@simula.no>, Martin Alnes <martinal@simula.no>, Ilmar M. Wilbers <ilmarw@simula.no>"20__date__="2009-05-28"21__version__="0.9.7"2223# TODO: Import only the official interface24fromoutputimport*25fromconfigimport*26frompathsimport*27fromsignaturesimport*28fromcacheimport*29fromcodegenerationimport*30frombuildimport*31frominliningimport*32
recompile(modulename,
module_path,
setup_name,
new_compilation_checksum)
Recompile module if the new checksum is different from the one in the
checksum file in the module directory.
Generate and compile a module from C/C++ code using SWIG.
Arguments:
The keyword arguments are as follows:
modulename:
The name you want for the module. If specified, the module will
not be cached. If missing, a name will be constructed based on
a checksum of the other arguments, and the module will be
placed in the global cache. String.
source_directory:
The directory where user supplied files reside. The files given
in sources, wrap_headers, and
local_headers are expected to exist in this directory.
String.
code:
A string containing C or C++ code to be compiled and wrapped.
String.
init_code:
Code that should be executed when the Instant module is
imported. This code is inserted in the SWIG interface file, and
is used for instance for calling import_array()
used for the initialization of NumPy arrays. String.
additional_definitions:
Additional definitions (typically needed for inheritance) for
interface file. These definitions should be given as
triple-quoted strings in the case they span multiple lines, and
are placed both in the initial block for C/C++ code
(%{,%}-block), and the main section of the
interface file. String.
additional_declarations:
Additional declarations (typically needed for inheritance) for
interface file. These declarations should be given as
triple-quoted strings in the case they span multiple lines, and
are plaves in the main section of the interface file. String.
sources:
Source files to compile and link with the module. These files
are compiled togehter with the SWIG-generated wrapper file into
the final library file. Should reside in directory specified in
source_directory. List of strings.
wrap_headers:
Local header files that should be wrapped by SWIG. The files
specified will be included both in the initial block for C/C++
code (with a C directive) and in the main section of the
interface file (with a SWIG directive). Should reside in
directory specified in source_directory. List of
strings.
local_headers:
Local header files required to compile the wrapped code. The
files specified will be included in the initial block for C/C++
code (with a C directive). Should reside in directory specified
in source_directory. List of strings.
system_headers:
System header files required to compile the wrapped code. The
files specified will be included in the initial block for C/C++
code (with a C directive). List of strings.
include_dirs:
Directories to search for header files for building the
extension module. Needs to be absolute path names. List of
strings.
library_dirs:
Directories to search for libraries (-l) for
building the extension module. Needs to be absolute paths. List
of strings.
libraries:
Libraries needed by the Instant module. The libraries will be
linked in from the shared object file. The initial
-l is added automatically. List of strings.
swigargs:
List of arguments to swig, e.g.
["-lpointers.i"] to include the SWIG
pointers.i library.
swig_include_dirs:
A list of directories to include in the 'swig' command.
cppargs:
List of arguments to the compiler, e.g.
["-Wall", "-fopenmp"].
lddargs:
List of arguments to the linker, e.g. ["-E",
"-U"].
object_files:
If you want to compile the files yourself. TODO: Not yet
supported.
arrays:
A nested list describing the C arrays to be made from NumPy
arrays. If the NumPy array is 1D, the inner list should contain
strings with the variable names for length of the array and the
array itself. If the NumPy array is a matrix or a tensor, the
inner list should contain strings with variable names for the
number of dimensions, the length in each dimension, and the
array itself, respectively.
generate_interface:
A bool to indicate if you want to generate the interface files.
generate_setup:
A bool to indicate if you want to generate the setup.py file.
signature:
A signature string to identify the form instead of the source
code.
cache_dir:
A directory to look for cached modules and place new ones. If
missing, a default directory is used. Note that the module will
not be cached if modulename is specified. The cache
directory should not be used for anything else.
40"""Copy a list of files from a source directory to a destination directory. 41 This may seem a bit complicated, but a lot of this code is error checking.""" 42ifos.path.exists(dest): 43overwriting=set(files)&set(glob.glob(os.path.join(dest,"*"))) 44ifoverwriting: 45instant_warning("In instant.copy_files: Path '%s' already exists, "\ 46"overwriting existing files: %r."%(dest,list(overwriting))) 47else: 48os.mkdir(dest) 49 50ifsource!=dest: 51instant_debug("In instant.copy_files: Copying files %r from %r to %r"\ 52%(files,source,dest)) 53 54forfinfiles: 55a=os.path.join(source,f) 56b=os.path.join(dest,f) 57instant_assert(a!=b,"In instant.copy_files: Seems like the "\ 58"input files are absolute paths, should be relative to "\ 59"source. (%r, %r)"%(a,b)) 60instant_assert(os.path.isfile(a),"In instant.copy_files: "\ 61"Missing source file '%s'."%a) 62ifos.path.isfile(b): 63os.remove(b) 64shutil.copyfile(a,b)
68"""Recompile module if the new checksum is different from 69 the one in the checksum file in the module directory.""" 70# Check if the old checksum matches the new one 71compilation_checksum_filename="%s.checksum"%modulename 72ifos.path.exists(compilation_checksum_filename): 73checksum_file=open(compilation_checksum_filename) 74old_compilation_checksum=checksum_file.readline() 75checksum_file.close() 76ifold_compilation_checksum==new_compilation_checksum: 77return 78 79# Verify that SWIG is on the system 80(swig_stat,swig_out)=get_status_output("swig -version") 81ifswig_stat!=0: 82instant_error("In instant.recompile: Could not find swig!"\ 83" You can download swig from http://www.swig.org") 84 85# Create log file for logging of compilation errors 86compile_log_filename=os.path.join(module_path,"compile.log") 87compile_log_file=open(compile_log_filename,"w") 88try: 89# Build module 90cmd="python %s build_ext"%setup_name 91instant_info("--- Instant: compiling ---") 92instant_debug("cmd = %s"%cmd) 93ret,output=get_status_output(cmd) 94compile_log_file.write(output) 95compile_log_file.flush() 96ifret!=0: 97ifos.path.exists(compilation_checksum_filename): 98os.remove(compilation_checksum_filename) 99instant_error("In instant.recompile: The module did not "\ 100"compile, see '%s'"%compile_log_filename)101102# 'Install' module103cmd="python %s install --install-platlib=."%setup_name104instant_debug("cmd = %s"%cmd)105ret,output=get_status_output(cmd)106compile_log_file.write(output)107compile_log_file.flush()108ifret!=0:109ifos.path.exists(compilation_checksum_filename):110os.remove(compilation_checksum_filename)111instant_error("In instant.recompile: Could not 'install' "\ 112"the module, see '%s'"%compile_log_filename)113finally:114compile_log_file.close()115116# Compilation succeeded, write new_compilation_checksum to checksum_file117write_file(compilation_checksum_filename,new_compilation_checksum)
121"Copy module directory to cache."122# Get lock, check if the module exists, _otherwise_ copy the123# finished compiled module from /tmp/foo to the cache directory,124# and then release lock125lock=get_lock(cache_dir,modulename)126127# Validate the path128cache_module_path=os.path.join(cache_dir,modulename)129ifos.path.exists(cache_module_path):130# This indicates a race condition has happened (and is being avoided!).131instant_warning("In instant.build_module: Path '%s' already exists,"\ 132" but module wasn't found in cache previously. Not overwriting,"\ 133" assuming this module is valid."%cache_module_path)134135release_lock(lock)136returncache_module_path137138# Not deleting anymore, relying on locking system139#shutil.rmtree(cache_module_path, ignore_errors=True)140141# Error checks142instant_assert(os.path.isdir(module_path),"In instant.build_module:"\ 143" Cannot copy non-existing directory %r!"%module_path)144instant_assert(notos.path.isdir(cache_module_path),145"In instant.build_module: Cache directory %r shouldn't exist "\ 146"at this point!"%cache_module_path)147instant_debug("In instant.build_module: Copying built module from %r"\ 148" to cache at %r"%(module_path,cache_module_path))149150# Do the copying151shutil.copytree(module_path,cache_module_path)152delete_temp_dir()153release_lock(lock)154returncache_module_path
169"""Generate and compile a module from C/C++ code using SWIG.170171 Arguments: 172 ==========173 The keyword arguments are as follows:174 - B{modulename}:175 - The name you want for the module.176 If specified, the module will not be cached.177 If missing, a name will be constructed based on178 a checksum of the other arguments, and the module179 will be placed in the global cache. String.180 - B{source_directory}:181 - The directory where user supplied files reside. The files182 given in B{sources}, B{wrap_headers}, and B{local_headers}183 are expected to exist in this directory. String.184 - B{code}:185 - A string containing C or C++ code to be compiled and wrapped. String.186 - B{init_code}:187 - Code that should be executed when the Instant module is188 imported. This code is inserted in the SWIG interface file, and is189 used for instance for calling C{import_array()} used for the190 initialization of NumPy arrays. String.191 - B{additional_definitions}:192 - Additional definitions (typically needed for inheritance)193 for interface file. These definitions should be given as triple-quoted194 strings in the case they span multiple lines, and are placed both in the195 initial block for C/C++ code (C{%{,%}}-block), and the main section196 of the interface file. String.197 - B{additional_declarations}:198 - Additional declarations (typically needed for inheritance)199 for interface file. These declarations should be given as triple-quoted200 strings in the case they span multiple lines, and are plaves in the main201 section of the interface file. String.202 - B{sources}:203 - Source files to compile and link with the module. These204 files are compiled togehter with the SWIG-generated wrapper file into205 the final library file. Should reside in directory specified in206 B{source_directory}. List of strings.207 - B{wrap_headers}:208 - Local header files that should be wrapped by SWIG. The209 files specified will be included both in the initial block for C/C++ code210 (with a C directive) and in the main section of the interface file (with211 a SWIG directive). Should reside in directory specified in212 B{source_directory}. List of strings.213 - B{local_headers}:214 - Local header files required to compile the wrapped215 code. The files specified will be included in the initial block for216 C/C++ code (with a C directive). Should reside in directory specified in217 B{source_directory}. List of strings.218 - B{system_headers}:219 - System header files required to compile the wrapped220 code. The files specified will be included in the initial block for C/C++221 code (with a C directive). List of strings.222 - B{include_dirs}:223 - Directories to search for header files for building the224 extension module. Needs to be absolute path names. List of strings.225 - B{library_dirs}:226 - Directories to search for libraries (C{-l}) for building227 the extension module. Needs to be absolute paths. List of strings.228 - B{libraries}:229 - Libraries needed by the Instant module. The libraries will230 be linked in from the shared object file. The initial C{-l} is added231 automatically. List of strings.232 - B{swigargs}:233 - List of arguments to swig, e.g. C{["-lpointers.i"]}234 to include the SWIG pointers.i library.235 - B{swig_include_dirs}:236 - A list of directories to include in the 'swig' command.237 - B{cppargs}:238 - List of arguments to the compiler, e.g. C{["-Wall", "-fopenmp"]}.239 - B{lddargs}:240 - List of arguments to the linker, e.g. C{["-E", "-U"]}.241 - B{object_files}:242 - If you want to compile the files yourself. TODO: Not yet supported.243 - B{arrays}:244 - A nested list describing the C arrays to be made from NumPy arrays.245 If the NumPy array is 1D, the inner list should contain strings with246 the variable names for length of the array and the array itself.247 If the NumPy array is a matrix or a tensor, the inner list should248 contain strings with variable names for the number of dimensions,249 the length in each dimension, and the array itself, respectively.250 - B{generate_interface}:251 - A bool to indicate if you want to generate the interface files.252 - B{generate_setup}:253 - A bool to indicate if you want to generate the setup.py file.254 - B{signature}:255 - A signature string to identify the form instead of the source code.256 - B{cache_dir}:257 - A directory to look for cached modules and place new ones.258 If missing, a default directory is used. Note that the module259 will not be cached if B{modulename} is specified.260 The cache directory should not be used for anything else.261 """262263# Store original directory to be able to restore later264original_path=os.getcwd()265266# --- Validate arguments 267268instant_assert(modulenameisNoneorisinstance(modulename,str),269"In instant.build_module: Expecting modulename to be string or None.")270assert_is_str(source_directory)271source_directory=os.path.abspath(source_directory)272assert_is_str(code)273assert_is_str(init_code)274assert_is_str(additional_definitions)275assert_is_str(additional_declarations)276sources=strip_strings(sources)277wrap_headers=strip_strings(wrap_headers)278local_headers=strip_strings(local_headers)279system_headers=strip_strings(system_headers)280include_dirs=strip_strings(include_dirs)281library_dirs=strip_strings(library_dirs)282libraries=strip_strings(libraries)283swigargs=arg_strings(swigargs)284swig_include_dirs=strip_strings(swig_include_dirs)285cppargs=arg_strings(cppargs)286lddargs=arg_strings(lddargs)287object_files=strip_strings(object_files)288arrays=[strip_strings(a)forainarrays]289assert_is_bool(generate_interface)290assert_is_bool(generate_setup)291instant_assert(signatureisNone \ 292orisinstance(signature,str) \ 293orhasattr(signature,"signature"),294"In instant.build_module: Expecting modulename to be string or None.")295instant_assert(not(signatureisnotNoneandmodulenameisnotNone),296"In instant.build_module: Can't have both modulename and signature.")297298# --- Replace arguments with defaults if necessary299300cache_dir=validate_cache_dir(cache_dir)301302# Split sources by file-suffix (.c or .cpp)303csrcs=[fforfinsourcesiff.endswith('.c')orf.endswith('.C')]304cppsrcs=[fforfinsourcesiff.endswith('.cpp')orf.endswith('.cxx')]305instant_assert(len(csrcs)+len(cppsrcs)==len(sources),306"In instant.build_module: Source files must have '.c' or '.cpp' suffix")307308# --- Debugging code309instant_debug('In instant.build_module:')310instant_debug('::: Begin Arguments :::')311instant_debug(' modulename: %r'%modulename)312instant_debug(' source_directory: %r'%source_directory)313instant_debug(' code: %r'%code)314instant_debug(' init_code: %r'%init_code)315instant_debug(' additional_definitions: %r'%additional_definitions)316instant_debug(' additional_declarations: %r'%additional_declarations)317instant_debug(' sources: %r'%sources)318instant_debug(' csrcs: %r'%csrcs)319instant_debug(' cppsrcs: %r'%cppsrcs)320instant_debug(' wrap_headers: %r'%wrap_headers)321instant_debug(' local_headers: %r'%local_headers)322instant_debug(' system_headers: %r'%system_headers)323instant_debug(' include_dirs: %r'%include_dirs)324instant_debug(' library_dirs: %r'%library_dirs)325instant_debug(' libraries: %r'%libraries)326instant_debug(' swigargs: %r'%swigargs)327instant_debug(' swig_include_dirs: %r'%swig_include_dirs)328instant_debug(' cppargs: %r'%cppargs)329instant_debug(' lddargs: %r'%lddargs)330instant_debug(' object_files: %r'%object_files)331instant_debug(' arrays: %r'%arrays)332instant_debug(' generate_interface: %r'%generate_interface)333instant_debug(' generate_setup: %r'%generate_setup)334instant_debug(' signature: %r'%signature)335instant_debug(' cache_dir: %r'%cache_dir)336instant_debug('::: End Arguments :::')337338# --- Setup module directory, making it and copying339# files to it if necessary, and compute a modulename340# if it isn't specified explicitly341342ifmodulenameisNone:343# Compute a signature if we have none passed by the user:344ifsignatureisNone:345# Collect arguments used for checksum creation,346# including everything that affects the interface347# file generation and module compilation.348checksum_args=( \ 349# We don't care about the modulename, that's what we're trying to construct!350#modulename,351# We don't care where the user code resides:352#source_directory,353code,init_code,354additional_definitions,355additional_declarations,356# Skipping filenames, since we use the file contents:357#sources, wrap_headers,358#local_headers,359system_headers,360include_dirs,library_dirs,libraries,361swig_include_dirs,swigargs,cppargs,lddargs,362object_files,arrays,363generate_interface,generate_setup,364# The signature isn't defined, and the cache_dir doesn't affect the module:365#signature, cache_dir)366)367allfiles=sources+wrap_headers+local_headers368allfiles=[os.path.join(source_directory,file)forfileinallfiles]369text="\n".join((str(a)forainchecksum_args))370signature=modulename_from_checksum(compute_checksum(text,allfiles))371modulename=signature372moduleids=[signature]373else:374module,moduleids=check_memory_cache(signature)375ifmodule:returnmodule376modulename=moduleids[-1]377378# Look for module in disk cache 379module=check_disk_cache(modulename,cache_dir,moduleids)380ifmodule:returnmodule381382# Make a temporary module path for compilation383module_path=os.path.join(get_temp_dir(),modulename)384instant_assert(notos.path.exists(module_path),385"In instant.build_module: Not expecting module_path to exist: '%s'"\ 386%module_path)387os.mkdir(module_path)388use_cache=True389else:390use_cache=False391moduleids=[]392module_path=os.path.join(original_path,modulename)393ifnotos.path.exists(module_path):394os.mkdir(module_path)395396## Look for module in memory cache397#module, moduleids = check_memory_cache(modulename)398#if module: return module399#instant_assert(modulename == moduleids[-1] and len(moduleids) == 1, "Logic breach.")400## Look for module in local directory401#module = check_disk_cache(modulename, original_path, moduleids)402#if module: return module403404# Wrapping rest of code in try-block to 405# clean up at the end if something fails.406try:407# --- Copy user-supplied files to module path408409module_path=os.path.abspath(module_path)410files_to_copy=sources+wrap_headers+local_headers+object_files411copy_files(source_directory,module_path,files_to_copy)412# At this point, all user input files should reside in module_path.413414# --- Generate additional files in module directory415os.chdir(module_path)416417# Generate __init__.py which imports compiled module contents418write_file("__init__.py","from %s import *"%modulename)419420# Generate SWIG interface if wanted421ifile_name="%s.i"%modulename422ifgenerate_interface:423write_interfacefile(ifile_name,modulename,code,init_code,424additional_definitions,additional_declarations,system_headers,425local_headers,wrap_headers,arrays)426427# Generate setup.py if wanted428setup_name="setup.py"429ifgenerate_setup:430write_setup(setup_name,modulename,csrcs,cppsrcs,local_headers, \ 431include_dirs,library_dirs,libraries,swig_include_dirs, \ 432swigargs,cppargs,lddargs)433434# --- Build module435436# At this point we have all the files, and can make the437# total checksum from all file contents. This is used to438# decide whether the module needs recompilation or not.439440# Compute new_compilation_checksum441# Collect arguments used for checksum creation,442# including everything that affects the module compilation.443# Since the interface file is included in allfiles, 444# we don't need stuff that modifies it here.445checksum_args=( \ 446# We don't care about the modulename, that's what447# we're trying to construct!448#modulename,449# We don't care where the user code resides:450#source_directory,451#code, init_code,452#additional_definitions, additional_declarations,453# Skipping filenames, since we use the file contents:454#sources, wrap_headers,455#local_headers,456system_headers,457include_dirs,library_dirs,libraries,458swigargs,swig_include_dirs,cppargs,lddargs,459object_files,#arrays,460#generate_interface, generate_setup,461# The signature isn't defined, and the462# cache_dir doesn't affect the module:463#signature, cache_dir)464)465text="\n".join((str(a)forainchecksum_args))466allfiles=sources+wrap_headers+local_headers+[ifile_name]467new_compilation_checksum=compute_checksum(text,allfiles)468469# Recompile if necessary470recompile(modulename,module_path,setup_name,new_compilation_checksum)471472# --- Load, cache, and return module473474# Copy compiled module to cache475ifuse_cache:476module_path=copy_to_cache(module_path,cache_dir,modulename)477478# Import module and place in memory cache479# Do not use locks if use_cache is False:480ifuse_cache:481lock=get_lock(cache_dir,modulename)482module=import_and_cache_module(module_path,modulename,moduleids)483ifuse_cache:484release_lock(lock)485ifnotmodule:486instant_error("Failed to import newly compiled module!")487488instant_debug("In instant.build_module: Returning %s from build_module."\ 489%module)490returnmodule491# The end!492493finally:494# Always get back to original directory.495os.chdir(original_path)496497instant_error("In instant.build_module: Should never reach this point!")
Import module from cache given its moduleid and an optional cache
directory.
The moduleid can be either
the module name
a signature string, of which a checksum is taken to look up in the
cache
a checksum string, which is used directly to look up in the cache
a hashable non-string object with a function moduleid.signature()
which is used to get a signature string
The hashable object is used to look up in the memory cache before
signature() is called. If the module is found on disk, it is placed in
the memory cache.
33"Import a module with the given module name that resides in the given path." 34sys.path.insert(0,path) 35try: 36module=__import__(modulename) 37except: 38instant_warning("In instant.import_module_directly: Failed to import module '%s' from '%s'."%(modulename,path)) 39module=None 40finally: 41sys.path.pop(0) 42returnmodule
47"Returns the cached module if found." 48module=_memory_cache.get(moduleid,None) 49instant_debug("Found '%s' in memory cache with key '%r'."%(module,moduleid)) 50returnmodule
54"Place a compiled module in cache with given id." 55_memory_cache[moduleid]=module 56instant_debug("Added module '%s' to cache with key '%r'."%(module,moduleid))
65module=import_module_directly(path,modulename) 66instant_assert(moduleisnotNone,"Failed to import module found in cache. Modulename: '%s'; Path: '%s'."%(modulename,path)) 67formoduleidinmoduleids: 68place_module_in_memory_cache(moduleid,module) 69returnmodule
73# Check memory cache first with the given moduleid 74moduleids=[moduleid] 75module=memory_cached_module(moduleid) 76ifmodule:returnmodule,moduleids 77 78# Get signature from moduleid if it isn't a string, 79# and check memory cache again 80ifhasattr(moduleid,"signature"): 81moduleid=moduleid.signature() 82instant_debug("In instant.check_memory_cache: Got signature "\ 83"'%s' from moduleid.signature()."%moduleid) 84module=memory_cached_module(moduleid) 85ifmodule: 86formoduleidinmoduleids: 87place_module_in_memory_cache(moduleid,module) 88returnmodule,moduleids 89moduleids.append(moduleid) 90 91# Construct a filename from the checksum of moduleid if it 92# isn't already a valid name, and check memory cache again 93ifnotis_valid_module_name(moduleid): 94moduleid=modulename_from_checksum(compute_checksum(moduleid)) 95instant_debug("In instant.check_memory_cache: Constructed module name "\ 96"'%s' from moduleid '%s'."%(moduleid,moduleids[-1])) 97module=memory_cached_module(moduleid) 98ifmodule:returnmodule,moduleids 99moduleids.append(moduleid)100101instant_debug("In instant.check_memory_cache: Failed to find module.")102returnNone,moduleids
106# Get file lock to avoid race conditions in cache107lock=get_lock(cache_dir,modulename)108109# Ensure a valid cache_dir110cache_dir=validate_cache_dir(cache_dir)111112# Check on disk, in current directory and cache directory113forpathin(os.getcwd(),cache_dir):114ifos.path.isdir(os.path.join(path,modulename)):115# Found existing directory, try to import and place in memory cache116module=import_and_cache_module(path,modulename,moduleids)117ifmodule:118instant_debug("In instant.check_disk_cache: Imported module "\ 119"'%s' from '%s'."%(modulename,path))120release_lock(lock)121returnmodule122else:123instant_debug("In instant.check_disk_cache: Failed to imported "\ 124"module '%s' from '%s'."%(modulename,path))125126# All attempts failed127instant_debug("In instant.check_disk_cache: Can't import module with modulename "\ 128"%r using cache directory %r."%(modulename,cache_dir))129release_lock(lock)130returnNone
134"""Import module from cache given its moduleid and an optional cache directory.135136 The moduleid can be either137 - the module name138 - a signature string, of which a checksum is taken to look up in the cache139 - a checksum string, which is used directly to look up in the cache140 - a hashable non-string object with a function moduleid.signature() which is used to get a signature string141 The hashable object is used to look up in the memory cache before signature() is called.142 If the module is found on disk, it is placed in the memory cache.143 """144# Look for module in memory cache145module,moduleids=check_memory_cache(moduleid)146ifmodule:returnmodule147148# Look for module in disk cache149modulename=moduleids[-1]150returncheck_disk_cache(modulename,cache_dir,moduleids)
12'''Reindent a multiline string to allow easier to read syntax. 13 14 Each line will be indented relative to the first non-empty line. 15 Start the first line without text like shown in this example:: 16 17 code = reindent(""" 18 Foo 19 Bar 20 Blatti 21 Ping 22 """) 23 24 makes all indentation relative to Foo. 25 ''' 26lines=code.split("\n") 27space="" 28# Get initial spaces from first non-empty line: 29forlinlines: 30ifl: 31r=re.search(r"^( [ ]*)",l) 32ifrisnotNone: 33space=r.groups()[0] 34break 35ifnotspace: 36returncode 37n=len(space) 38instant_assert(space==" "*n,"Logic breach in reindent.") 39return"\n".join(re.sub(r"^%s"%space,"",l)forlinlines)
45"""Generate a SWIG interface file. Intended for internal library use. 46 47 The input arguments are as follows: 48 - modulename (Name of the module) 49 - code (Code to be wrapped) 50 - init_code (Code to put in the init section of the interface file) 51 - additional_definitions (Definitions to be placed in initial block with 52 C code as well as in the main section of the SWIG interface file) 53 - additional_declarations (Declarations to be placed in the main section 54 of the SWIG interface file) 55 - system_headers (A list of system headers with declarations needed by the wrapped code) 56 - local_headers (A list of local headers with declarations needed by the wrapped code) 57 - wrap_headers (A list of local headers that will be included in the code and wrapped by SWIG) 58 - arrays (A nested list, the inner lists describing the different arrays) 59 60 The result of this function is that a SWIG interface with 61 the name modulename.i is written to the current directory. 62 """ 63instant_debug("Generating SWIG interface file '%s'."%filename) 64 65# create typemaps 66typemaps="" 67valid_types=['float','double','short','int','long', 68'unsigned short','unsigned int','unsigned long'] 69DATA_TYPE='double' 70forainarrays: 71iftype(a)==tuple: 72a=list(a) 73forvtinvalid_types: 74ifvtina: 75DATA_TYPE=vt 76a.remove(vt) 77if'in'ina: 78# input arrays 79a.remove('in') 80instant_assert(len(a)>1andlen(a)<5,"Wrong number of elements in input array") 81iflen(a)==2: 82# 1-dimensional arrays, i.e. vectors 83typemaps+=reindent(""" 84 %%apply (int DIM1, %(dtype)s* IN_ARRAY1) {(int %(n1)s, %(dtype)s* %(array)s)}; 85 """%{'n1':a[0],'array':a[1],'dtype':DATA_TYPE}) 86eliflen(a)==3: 87# 2-dimensional arrays, i.e. matrices 88typemaps+=reindent(""" 89 %%apply (int DIM1, int DIM2, %(dtype)s* IN_ARRAY2) {(int %(n1)s, int %(n2)s, %(dtype)s* %(array)s)}; 90 """%{'n1':a[0],'n2':a[1],'array':a[2],'dtype':DATA_TYPE}) 91else: 92# 3-dimensional arrays, i.e. tensors 93typemaps+=reindent(""" 94 %%apply (int DIM1, int DIM2, int DIM3, %(dtype)s* IN_ARRAY3) {(int %(n1)s, int %(n2)s, int %(n3)s, %(dtype)s* %(array)s)}; 95 """%{'n1':a[0],'n2':a[1],'n3':a[2],'array':a[3],'dtype':DATA_TYPE}) 96elif'out'ina: 97# output arrays 98a.remove('out') 99instant_assert(len(a)==2,"Output array must be 1-dimensional")100# 1-dimensional arrays, i.e. vectors101typemaps+=reindent("""102 %%apply (int DIM1, %(dtype)s* ARGOUT_ARRAY1) {(int %(n1)s, %(dtype)s* %(array)s)};103 """%{'n1':a[0],'array':a[1],'dtype':DATA_TYPE})104else:105# in-place arrays106instant_assert(len(a)>1andlen(a)<5,"Wrong number of elements in output array")107if'multi'ina:108# n-dimensional arrays, i.e. tensors > 3-dimensional109a.remove('multi')110typemaps+=reindent("""111 %%typemap(in) (int %(n)s,int* %(ptv)s,%(dtype)s* %(array)s){112 if (!PyArray_Check($input)) { 113 PyErr_SetString(PyExc_TypeError, "Not a NumPy array");114 return NULL; ;115 }116 PyArrayObject* pyarray;117 pyarray = (PyArrayObject*)$input; 118 $1 = int(pyarray->nd);119 int* dims = new int($1); 120 for (int d=0; d<$1; d++) {121 dims[d] = int(pyarray->dimensions[d]);122 }123124 $2 = dims; 125 $3 = (%(dtype)s*)pyarray->data;126 }127 %%typemap(freearg) (int %(n)s,int* %(ptv)s,%(dtype)s* %(array)s){128 // deleting dims129 delete $2; 130 }131 """%{'n':a[0],'ptv':a[1],'array':a[2],'dtype':DATA_TYPE})132eliflen(a)==2:133# 1-dimensional arrays, i.e. vectors134typemaps+=reindent("""135 %%apply (int DIM1, %(dtype)s* INPLACE_ARRAY1) {(int %(n1)s, %(dtype)s* %(array)s)};136 """%{'n1':a[0],'array':a[1],'dtype':DATA_TYPE})137eliflen(a)==3:138# 2-dimensional arrays, i.e. matrices139typemaps+=reindent("""140 %%apply (int DIM1, int DIM2, %(dtype)s* INPLACE_ARRAY2) {(int %(n1)s, int %(n2)s, %(dtype)s* %(array)s)};141 """%{'n1':a[0],'n2':a[1],'array':a[2],'dtype':DATA_TYPE})142else:143# 3-dimensional arrays, i.e. tensors144typemaps+=reindent("""145 %%apply (int DIM1, int DIM2, int DIM3, %(dtype)s* INPLACE_ARRAY3) {(int %(n1)s, int %(n2)s, int %(n3)s, %(dtype)s* %(array)s)};146 """%{'n1':a[0],'n2':a[1],'n3':a[2],'array':a[3],'dtype':DATA_TYPE})147# end148# end if149# end for150151system_headers_code=mapstrings('#include <%s>',system_headers)152local_headers_code=mapstrings('#include "%s"',local_headers)153wrap_headers_code1=mapstrings('#include "%s"',wrap_headers)154wrap_headers_code2=mapstrings('%%include "%s"',wrap_headers)155156numpy_i_include=''157ifarrays:158numpy_i_include=r'%include "numpy.i"'159160interface_string=reindent("""161 %%module %(modulename)s162 //%%module (directors="1") %(modulename)s163164 //%%feature("director");165166 %%{167 #include <iostream>168 %(additional_definitions)s 169 %(system_headers_code)s 170 %(local_headers_code)s 171 %(wrap_headers_code1)s 172 %(code)s173 %%}174175 //%%feature("autodoc", "1");176 %(numpy_i_include)s177178 %%init%%{179 %(init_code)s180 %%}181182 %(additional_definitions)s183 %(additional_declarations)s184 %(wrap_headers_code2)s185 //%(typemaps)s186 %(code)s;187188 """%locals())189190write_file(filename,interface_string)191instant_debug("Done generating interface file.")
header_and_libs_from_pkgconfig(*packages,
**kwargs)
This function returns list of include files, flags, libraries and
library directories obtain from a pkgconfig file.
Check the swig version
Returns True if the version of the installed swig is equal or greater than the
version passed to the function.
If same is True, the function returns True if and only if the two versions
are the same.
Usage:
if instant.check_swig_version('1.3.36'):
print "Swig version is greater than or equal to 1.3.36"
else:
print "Swig version is lower than 1.3.36"
8""" Return the current swig version in a 'str'""" 9# Check for swig installation 10result,output=get_status_output("swig -version") 11ifresult!=0: 12raiseOSError("SWIG is not installed on the system.") 13pattern="SWIG Version (.*)" 14r=re.search(pattern,output) 15returnr.groups(0)[0] 16
18""" Check the swig version 19 20 Returns True if the version of the installed swig is equal or greater than the 21 version passed to the function. 22 23 If same is True, the function returns True if and only if the two versions 24 are the same. 25 26 Usage: 27 if instant.check_swig_version('1.3.36'): 28 print "Swig version is greater than or equal to 1.3.36" 29 else: 30 print "Swig version is lower than 1.3.36" 31 """ 32assertisinstance(version,str),"Provide the first version number as a 'str'" 33assertlen(version.split("."))==3,"Provide the version number as three numbers seperated by '.'" 34 35installed_version=map(int,get_swig_version().split('.')) 36handed_version=map(int,version.split('.')) 37 38# If same is True then just check that all numbers are equal 39ifsame: 40returnall(i==hfori,hinzip(installed_version,handed_version)) 41 42swig_enough=True 43fori,vinenumerate([vforvininstalled_version]): 44ifhanded_version[i]<v: 45break 46elifhanded_version[i]==v: 47continue 48else: 49swig_enough=False 50break 51 52returnswig_enough
This is a short wrapper around the build_module function in
instant.
It creates a module given that the input is a valid C function. It is
only possible to inline one C function each time.
Usage:
>>> from instant import inline
>>> add_func = inline("double add(double a, double b){ return a+b; }")
>>> print"The sum of 3 and 4.5 is ", add_func(3, 4.5)
This is a short wrapper around the build_module function in
instant.
It creates a module given that the input is a valid C function. It is
only possible to inline one C function each time.
Usage:
>>> from instant import inline
>>> add_func = inline("double add(double a, double b){ return a+b; }")
>>> print"The sum of 3 and 4.5 is ", add_func(3, 4.5)
This is a short wrapper around the build_module function in
instant.
It creates a module given that the input is a valid C function. It is
only possible to inline one C function each time. The difference between
this function and the inline function is that C-arrays can be used. The
following example illustrates that.
Usage:
>>> import numpy
>>> import time
>>> from instant import inline_with_numpy
>>> c_code = """
double sum (int n1, double* array1){ double tmp = 0.0; for (int i=0; i<n1; i++) { tmp += array1[i]; } return tmp; } """>>> sum_func = inline_with_numpy(c_code, arrays = [['n1', 'array1']])
>>> a = numpy.arange(10000000); a = numpy.sin(a)
>>> sum_func(a)
This is a short wrapper around the build_module function in
instant.
It creates a module given that the input is a valid C function. It is
only possible to inline one C function each time. The difference between
this function and the inline function is that C-arrays can be used. The
following example illustrates that.
Usage:
>>> import numpy
>>> import time
>>> from instant import inline_with_numpy
>>> c_code = """
double sum (int n1, double* array1){ double tmp = 0.0; for (int i=0; i<n1; i++) { tmp += array1[i]; } return tmp; } """>>> sum_func = inline_with_numpy(c_code, arrays = [['n1', 'array1']])
>>> a = numpy.arange(10000000); a = numpy.sin(a)
>>> sum_func(a)
9# TODO: Something more robust? Regexp? 10try: 11func=c_code[:c_code.index('(')] 12ret,func_name=func.split() 13except: 14instant_error("Failed to extract function name from c_code.") 15returnfunc_name
19"""This is a short wrapper around the build_module function in instant. 20 21 It creates a module given that 22 the input is a valid C function. It is only possible 23 to inline one C function each time. 24 25 Usage: 26 27 >>> from instant import inline 28 >>> add_func = inline("double add(double a, double b){ return a+b; }") 29 >>> print "The sum of 3 and 4.5 is ", add_func(3, 4.5) 30 """ 31instant_assert("code"notinkwargs,"Cannot specify code twice.") 32kwargs["code"]=c_code 33func_name=get_func_name(c_code) 34module=build_module(**kwargs) 35ifhasattr(module,func_name): 36returngetattr(module,func_name) 37else: 38instant_warning("Didn't find function '%s', returning module."%func_name) 39returnmodule
42"""This is a short wrapper around the build_module function in instant. 43 44 It creates a module given that 45 the input is a valid C function. It is only possible 46 to inline one C function each time. 47 48 Usage: 49 50 >>> from instant import inline 51 >>> add_func = inline("double add(double a, double b){ return a+b; }") 52 >>> print "The sum of 3 and 4.5 is ", add_func(3, 4.5) 53 """ 54instant_assert("code"notinkwargs,"Cannot specify code twice.") 55kwargs["code"]=c_code 56module=build_module(**kwargs) 57returnmodule
62'''This is a short wrapper around the build_module function in instant. 63 64 It creates a module given that 65 the input is a valid C function. It is only possible 66 to inline one C function each time. The difference between 67 this function and the inline function is that C-arrays can be used. 68 The following example illustrates that. 69 70 Usage: 71 72 >>> import numpy 73 >>> import time 74 >>> from instant import inline_with_numpy 75 >>> c_code = """ 76 double sum (int n1, double* array1){ 77 double tmp = 0.0; 78 for (int i=0; i<n1; i++) { 79 tmp += array1[i]; 80 } 81 return tmp; 82 } 83 """ 84 >>> sum_func = inline_with_numpy(c_code, arrays = [['n1', 'array1']]) 85 >>> a = numpy.arange(10000000); a = numpy.sin(a) 86 >>> sum_func(a) 87 ''' 88importnumpy 89instant_assert("code"notinkwargs,"Cannot specify code twice.") 90kwargs["code"]=c_code 91kwargs["init_code"]=kwargs.get("init_code","")+"\nimport_array();\n" 92kwargs["system_headers"]=kwargs.get("system_headers",[])+["numpy/arrayobject.h"] 93kwargs["include_dirs"]=kwargs.get("include_dirs",[])+["%s"%numpy.get_include()] 94func_name=get_func_name(c_code) 95module=build_module(**kwargs) 96ifhasattr(module,func_name): 97returngetattr(module,func_name) 98else: 99instant_warning("Didn't find function '%s', returning module."%func_name)100returnmodule
103'''This is a short wrapper around the build_module function in instant. 104105 It creates a module given that106 the input is a valid C function. It is only possible107 to inline one C function each time. The difference between108 this function and the inline function is that C-arrays can be used. 109 The following example illustrates that. 110111 Usage: 112113 >>> import numpy114 >>> import time115 >>> from instant import inline_with_numpy116 >>> c_code = """117 double sum (int n1, double* array1){118 double tmp = 0.0; 119 for (int i=0; i<n1; i++) { 120 tmp += array1[i]; 121 }122 return tmp; 123 }124 """125 >>> sum_func = inline_with_numpy(c_code, arrays = [['n1', 'array1']])126 >>> a = numpy.arange(10000000); a = numpy.sin(a)127 >>> sum_func(a)128 '''129importnumpy130instant_assert("code"notinkwargs,"Cannot specify code twice.")131kwargs["code"]=c_code132kwargs["init_code"]=kwargs.get("init_code","")+"\nimport_array();\n"133kwargs["system_headers"]=kwargs.get("system_headers",[])+["numpy/arrayobject.h"]134kwargs["include_dirs"]=kwargs.get("include_dirs",[])+["%s"%numpy.get_include()]135module=build_module(**kwargs)136returnmodule
generate_Makefile(self)
Generates a project dependent Makefile, which includes and uses
SWIG's own Makefile to create an extension module of the supplied
C/C++ code.
Check if the md5sum of the generated interface file has changed since
the last time the module was compiled. If it has changed then
recompilation is necessary.
1"""File locking for the cache system, to avoid problems 2when multiple processes work with the same module. 3Only works on UNIX systems.""" 4 5importos.path 6fromoutputimportinstant_error,instant_assert,instant_debug 7frompathsimportvalidate_cache_dir 8 9try:10importfcntl11except:12fcntl=None1314# Keeping an overview of locks currently held,15# to avoid deadlocks within a single process.16_lock_names={}# lock.fileno() -> lockname17_lock_files={}# lockname -> lock18_lock_count={}# lockname -> number of times this lock has been aquired and not yet released1920iffcntl:
22"Get a new file lock."23global_lock_names,_lock_files,_lock_count2425lockname=module_name+".lock"26count=_lock_count.get(lockname,0)2728instant_debug("Acquiring lock %s, count is %d."%(lockname,count))2930ifcount==0:31cache_dir=validate_cache_dir(cache_dir)32lock=open(os.path.join(cache_dir,lockname),"w")33fcntl.flock(lock.fileno(),fcntl.LOCK_EX)34_lock_names[lock.fileno()]=lockname35_lock_files[lockname]=lock36else:37lock=_lock_files[lockname]3839_lock_count[lockname]=count+140returnlock
43"Release a lock currently held by Instant."44global_lock_names,_lock_files,_lock_count4546lockname=_lock_names[lock.fileno()]47count=_lock_count[lockname]4849instant_debug("Releasing lock %s, count is %d."%(lockname,count))5051instant_assert(count>0,"Releasing lock that Instant is supposedly not holding.")52instant_assert(lockis_lock_files[lockname],"Lock mismatch, might be something wrong in locking logic.")5354del_lock_files[lockname]55del_lock_names[lock.fileno()]56_lock_count[lockname]=count-15758fcntl.flock(lock.fileno(),fcntl.LOCK_UN)59lock.close()
60"Write text to a file and close it."61try:62f=open(filename,"w")63f.write(text)64f.close()65exceptIOError,e:66instant_error("Can't open '%s': %s"%(filename,e))
676869# Taken from http://ivory.idyll.org/blog/mar-07/replacing-commands-with-subprocess70fromsubprocessimportPopen,PIPE,STDOUT
1"""This module contains helper functions for working with temp and cache directories.""" 2 3# Utilities for directory handling: 4 5importos 6importshutil 7importtempfile 8importtime 9fromoutputimportinstant_debug,instant_assert1011_tmp_dir=None
13"""Return a temporary directory for the duration of this process.1415 Multiple calls in the same process returns the same directory.16 Remember to all delete_temp_dir() before exiting."""17global_tmp_dir18if_tmp_dirisNone:19datestring="%d-%d-%d-%02d-%02d"%time.localtime()[:5]20suffix=datestring+"_instant"21_tmp_dir=tempfile.mkdtemp(suffix)22instant_debug("Created temp directory '%s'."%_tmp_dir)23return_tmp_dir
26"""Delete the temporary directory created by get_temp_dir()."""27global_tmp_dir28if_tmp_dirandos.path.isdir(_tmp_dir):29shutil.rmtree(_tmp_dir,ignore_errors=True)30_tmp_dir=None
33"Return a temporary directory for the duration of this process."34# os.path.expanduser works for Windows, Linux, and Mac35# In Windows, $HOME is os.environ['HOMEDRIVE'] + os.environ['HOMEPATH']36instant_dir=os.path.join(os.path.expanduser("~"),".instant")37ifnotos.path.isdir(instant_dir):38instant_debug("Creating instant directory '%s'."%instant_dir)39os.mkdir(instant_dir)40returninstant_dir
51ifcache_dirisNone:52returnget_default_cache_dir()53instant_assert(isinstance(cache_dir,str),"Expecting cache_dir to be a string.")54cache_dir=os.path.abspath(cache_dir)55ifnotos.path.isdir(cache_dir):56os.mkdir(cache_dir)57returncache_dir
7""" 8 Get the checksum value of filename 9 modified based on Python24\Tools\Scripts\md5.py10 """11instant_assert(isinstance(text,str),"Expecting string.")12instant_assert(isinstance(filenames,(list,tuple)),"Expecting sequence.")1314m=hashlib.new('sha1')15iftext:16m.update(text)1718forfilenameinsorted(filenames):19instant_debug("Adding file '%s' to checksum."%filename)20try:21fp=open(filename,'rb')22exceptIOError,e:23instant_error("Can't open file '%s': %s"%(filename,e))2425try:26while1:27data=fp.read()28ifnotdata:29break30m.update(data)31exceptIOError,e:32instant_error("I/O error reading '%s': %s"%(filename,e))3334fp.close()3536returnm.hexdigest().lower()
When javascript is enabled, this page will redirect URLs of
the form redirect.html#dotted.name to the
documentation for the object with the given fully-qualified
dotted name.