Merge lp:~corey.bryant/ubuntu/vivid/python-pint/0.6 into lp:ubuntu/vivid/python-pint
- Vivid (15.04)
- 0.6
- Merge into vivid
Proposed by
Corey Bryant
Status: | Merged |
---|---|
Merge reported by: | Martin Pitt |
Merged at revision: | not available |
Proposed branch: | lp:~corey.bryant/ubuntu/vivid/python-pint/0.6 |
Merge into: | lp:ubuntu/vivid/python-pint |
Diff against target: |
4777 lines (+2647/-1094) 41 files modified
.gitignore (+0/-14) .pc/applied-patches (+0/-2) .pc/no-intersphinx.patch/docs/conf.py (+0/-299) .pc/removes-privacy-breach-in-doc.patch/docs/_themes/flask/layout.html (+0/-30) .pc/removes-privacy-breach-in-doc.patch/docs/conf.py (+0/-299) .travis.yml (+0/-65) AUTHORS (+7/-1) CHANGES (+33/-0) CHANGES_DEV (+5/-0) MANIFEST.in (+1/-1) PKG-INFO (+400/-0) Pint.egg-info/PKG-INFO (+400/-0) Pint.egg-info/SOURCES.txt (+72/-0) Pint.egg-info/dependency_links.txt (+1/-0) Pint.egg-info/entry_points.txt (+3/-0) Pint.egg-info/top_level.txt (+1/-0) Pint.egg-info/zip-safe (+1/-0) debian/changelog (+7/-0) debian/control (+2/-0) debian/watch (+2/-2) docs/_themes/flask/layout.html (+1/-1) docs/conf.py (+1/-1) docs/contexts.rst (+13/-1) docs/faq.rst (+2/-0) docs/index.rst (+1/-1) docs/nonmult.rst (+126/-27) docs/serialization.rst (+3/-2) docs/tutorial.rst (+0/-1) pint/__init__.py (+49/-14) pint/default_en.txt (+34/-4) pint/quantity.py (+360/-74) pint/testsuite/parameterized.py (+152/-0) pint/testsuite/test_issues.py (+10/-5) pint/testsuite/test_numpy.py (+70/-16) pint/testsuite/test_quantity.py (+553/-10) pint/testsuite/test_umath.py (+91/-32) pint/testsuite/test_unit.py (+66/-24) pint/unit.py (+170/-87) setup.cfg (+9/-3) setup.py (+1/-1) tox.ini (+0/-77) |
To merge this branch: | bzr merge lp:~corey.bryant/ubuntu/vivid/python-pint/0.6 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Development Team | Pending | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Martin Pitt (pitti) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed file '.gitignore' | |||
2 | --- .gitignore 2014-09-05 23:26:05 +0000 | |||
3 | +++ .gitignore 1970-01-01 00:00:00 +0000 | |||
4 | @@ -1,14 +0,0 @@ | |||
5 | 1 | *~ | ||
6 | 2 | __pycache__ | ||
7 | 3 | *egg-info* | ||
8 | 4 | *.pyc | ||
9 | 5 | .DS_Store | ||
10 | 6 | docs/_build/ | ||
11 | 7 | .idea | ||
12 | 8 | build/ | ||
13 | 9 | dist/ | ||
14 | 10 | MANIFEST | ||
15 | 11 | .tox | ||
16 | 12 | |||
17 | 13 | # WebDAV file system cache files | ||
18 | 14 | .DAV/ | ||
19 | 15 | 0 | ||
20 | === removed file '.pc/applied-patches' | |||
21 | --- .pc/applied-patches 2014-09-05 23:26:05 +0000 | |||
22 | +++ .pc/applied-patches 1970-01-01 00:00:00 +0000 | |||
23 | @@ -1,2 +0,0 @@ | |||
24 | 1 | no-intersphinx.patch | ||
25 | 2 | removes-privacy-breach-in-doc.patch | ||
26 | 3 | 0 | ||
27 | === removed directory '.pc/no-intersphinx.patch' | |||
28 | === removed directory '.pc/no-intersphinx.patch/docs' | |||
29 | === removed file '.pc/no-intersphinx.patch/docs/conf.py' | |||
30 | --- .pc/no-intersphinx.patch/docs/conf.py 2014-09-05 23:26:05 +0000 | |||
31 | +++ .pc/no-intersphinx.patch/docs/conf.py 1970-01-01 00:00:00 +0000 | |||
32 | @@ -1,299 +0,0 @@ | |||
33 | 1 | #!/usr/bin/env python3 | ||
34 | 2 | # -*- coding: utf-8 -*- | ||
35 | 3 | # | ||
36 | 4 | # pint documentation build configuration file, created by | ||
37 | 5 | # sphinx-quickstart on Thu Mar 1 13:33:14 2012. | ||
38 | 6 | # | ||
39 | 7 | # This file is execfile()d with the current directory set to its containing dir. | ||
40 | 8 | # | ||
41 | 9 | # Note that not all possible configuration values are present in this | ||
42 | 10 | # autogenerated file. | ||
43 | 11 | # | ||
44 | 12 | # All configuration values have a default; values that are commented out | ||
45 | 13 | # serve to show the default. | ||
46 | 14 | |||
47 | 15 | import sys, os | ||
48 | 16 | import pkg_resources | ||
49 | 17 | import datetime | ||
50 | 18 | |||
51 | 19 | # If extensions (or modules to document with autodoc) are in another directory, | ||
52 | 20 | # add these directories to sys.path here. If the directory is relative to the | ||
53 | 21 | # documentation root, use os.path.abspath to make it absolute, like shown here. | ||
54 | 22 | #sys.path.insert(0, os.path.abspath('.')) | ||
55 | 23 | |||
56 | 24 | # -- General configuration ----------------------------------------------------- | ||
57 | 25 | |||
58 | 26 | # If your documentation needs a minimal Sphinx version, state it here. | ||
59 | 27 | #needs_sphinx = '1.0' | ||
60 | 28 | |||
61 | 29 | # Add any Sphinx extension module names here, as strings. They can be extensions | ||
62 | 30 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. | ||
63 | 31 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.coverage', 'sphinx.ext.viewcode', 'sphinx.ext.mathjax'] | ||
64 | 32 | |||
65 | 33 | # Add any paths that contain templates here, relative to this directory. | ||
66 | 34 | templates_path = ['_templates'] | ||
67 | 35 | |||
68 | 36 | # The suffix of source filenames. | ||
69 | 37 | source_suffix = '.rst' | ||
70 | 38 | |||
71 | 39 | # The encoding of source files. | ||
72 | 40 | #source_encoding = 'utf-8-sig' | ||
73 | 41 | |||
74 | 42 | # The master toctree document. | ||
75 | 43 | master_doc = 'index' | ||
76 | 44 | |||
77 | 45 | # General information about the project. | ||
78 | 46 | project = 'pint' | ||
79 | 47 | author = 'Hernan E. Grecco' | ||
80 | 48 | |||
81 | 49 | # The version info for the project you're documenting, acts as replacement for | ||
82 | 50 | # |version| and |release|, also used in various other places throughout the | ||
83 | 51 | # built documents. | ||
84 | 52 | |||
85 | 53 | version = pkg_resources.get_distribution(project).version | ||
86 | 54 | release = version | ||
87 | 55 | this_year = datetime.date.today().year | ||
88 | 56 | copyright = '%s, %s' % (this_year, author) | ||
89 | 57 | |||
90 | 58 | # The language for content autogenerated by Sphinx. Refer to documentation | ||
91 | 59 | # for a list of supported languages. | ||
92 | 60 | #language = None | ||
93 | 61 | |||
94 | 62 | # There are two options for replacing |today|: either, you set today to some | ||
95 | 63 | # non-false value, then it is used: | ||
96 | 64 | #today = '' | ||
97 | 65 | # Else, today_fmt is used as the format for a strftime call. | ||
98 | 66 | #today_fmt = '%B %d, %Y' | ||
99 | 67 | |||
100 | 68 | # List of patterns, relative to source directory, that match files and | ||
101 | 69 | # directories to ignore when looking for source files. | ||
102 | 70 | exclude_patterns = ['_build'] | ||
103 | 71 | |||
104 | 72 | # The reST default role (used for this markup: `text`) to use for all documents. | ||
105 | 73 | #default_role = None | ||
106 | 74 | |||
107 | 75 | # If true, '()' will be appended to :func: etc. cross-reference text. | ||
108 | 76 | #add_function_parentheses = True | ||
109 | 77 | |||
110 | 78 | # If true, the current module name will be prepended to all description | ||
111 | 79 | # unit titles (such as .. function::). | ||
112 | 80 | #add_module_names = True | ||
113 | 81 | |||
114 | 82 | # If true, sectionauthor and moduleauthor directives will be shown in the | ||
115 | 83 | # output. They are ignored by default. | ||
116 | 84 | #show_authors = False | ||
117 | 85 | |||
118 | 86 | # The name of the Pygments (syntax highlighting) style to use. | ||
119 | 87 | pygments_style = 'sphinx' | ||
120 | 88 | |||
121 | 89 | # A list of ignored prefixes for module index sorting. | ||
122 | 90 | #modindex_common_prefix = [] | ||
123 | 91 | |||
124 | 92 | |||
125 | 93 | # -- Options for HTML output --------------------------------------------------- | ||
126 | 94 | |||
127 | 95 | # The theme to use for HTML and HTML Help pages. See the documentation for | ||
128 | 96 | # a list of builtin themes. | ||
129 | 97 | #html_theme = 'default' | ||
130 | 98 | html_theme = 'flask' | ||
131 | 99 | |||
132 | 100 | # Theme options are theme-specific and customize the look and feel of a theme | ||
133 | 101 | # further. For a list of options available for each theme, see the | ||
134 | 102 | # documentation. | ||
135 | 103 | #html_theme_options = {} | ||
136 | 104 | |||
137 | 105 | # Add any paths that contain custom themes here, relative to this directory. | ||
138 | 106 | #html_theme_path = [] | ||
139 | 107 | html_theme_path = ['_themes'] | ||
140 | 108 | |||
141 | 109 | # The name for this set of Sphinx documents. If None, it defaults to | ||
142 | 110 | # "<project> v<release> documentation". | ||
143 | 111 | #html_title = None | ||
144 | 112 | |||
145 | 113 | # A shorter title for the navigation bar. Default is the same as html_title. | ||
146 | 114 | #html_short_title = None | ||
147 | 115 | |||
148 | 116 | # The name of an image file (relative to this directory) to place at the top | ||
149 | 117 | # of the sidebar. | ||
150 | 118 | #html_logo = None | ||
151 | 119 | |||
152 | 120 | # The name of an image file (within the static path) to use as favicon of the | ||
153 | 121 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 | ||
154 | 122 | # pixels large. | ||
155 | 123 | #html_favicon = None | ||
156 | 124 | |||
157 | 125 | # Add any paths that contain custom static files (such as style sheets) here, | ||
158 | 126 | # relative to this directory. They are copied after the builtin static files, | ||
159 | 127 | # so a file named "default.css" will overwrite the builtin "default.css". | ||
160 | 128 | html_static_path = ['_static'] | ||
161 | 129 | |||
162 | 130 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, | ||
163 | 131 | # using the given strftime format. | ||
164 | 132 | #html_last_updated_fmt = '%b %d, %Y' | ||
165 | 133 | |||
166 | 134 | # If true, SmartyPants will be used to convert quotes and dashes to | ||
167 | 135 | # typographically correct entities. | ||
168 | 136 | #html_use_smartypants = True | ||
169 | 137 | |||
170 | 138 | # Custom sidebar templates, maps document names to template names. | ||
171 | 139 | #html_sidebars = {} | ||
172 | 140 | html_sidebars = { | ||
173 | 141 | 'index': ['sidebarintro.html', 'sourcelink.html', 'searchbox.html'], | ||
174 | 142 | '**': ['sidebarlogo.html', 'localtoc.html', 'relations.html', | ||
175 | 143 | 'sourcelink.html', 'searchbox.html'] | ||
176 | 144 | } | ||
177 | 145 | |||
178 | 146 | # Additional templates that should be rendered to pages, maps page names to | ||
179 | 147 | # template names. | ||
180 | 148 | #html_additional_pages = {} | ||
181 | 149 | |||
182 | 150 | # If false, no module index is generated. | ||
183 | 151 | #html_domain_indices = True | ||
184 | 152 | |||
185 | 153 | # If false, no index is generated. | ||
186 | 154 | #html_use_index = True | ||
187 | 155 | |||
188 | 156 | # If true, the index is split into individual pages for each letter. | ||
189 | 157 | #html_split_index = False | ||
190 | 158 | |||
191 | 159 | # If true, links to the reST sources are added to the pages. | ||
192 | 160 | #html_show_sourcelink = True | ||
193 | 161 | |||
194 | 162 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. | ||
195 | 163 | #html_show_sphinx = True | ||
196 | 164 | |||
197 | 165 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. | ||
198 | 166 | #html_show_copyright = True | ||
199 | 167 | |||
200 | 168 | # If true, an OpenSearch description file will be output, and all pages will | ||
201 | 169 | # contain a <link> tag referring to it. The value of this option must be the | ||
202 | 170 | # base URL from which the finished HTML is served. | ||
203 | 171 | #html_use_opensearch = '' | ||
204 | 172 | |||
205 | 173 | # This is the file name suffix for HTML files (e.g. ".xhtml"). | ||
206 | 174 | #html_file_suffix = None | ||
207 | 175 | |||
208 | 176 | # Output file base name for HTML help builder. | ||
209 | 177 | htmlhelp_basename = 'pintdoc' | ||
210 | 178 | |||
211 | 179 | |||
212 | 180 | # -- Options for LaTeX output -------------------------------------------------- | ||
213 | 181 | |||
214 | 182 | latex_elements = { | ||
215 | 183 | # The paper size ('letterpaper' or 'a4paper'). | ||
216 | 184 | #'papersize': 'letterpaper', | ||
217 | 185 | |||
218 | 186 | # The font size ('10pt', '11pt' or '12pt'). | ||
219 | 187 | #'pointsize': '10pt', | ||
220 | 188 | |||
221 | 189 | # Additional stuff for the LaTeX preamble. | ||
222 | 190 | #'preamble': '', | ||
223 | 191 | } | ||
224 | 192 | |||
225 | 193 | # Grouping the document tree into LaTeX files. List of tuples | ||
226 | 194 | # (source start file, target name, title, author, documentclass [howto/manual]). | ||
227 | 195 | latex_documents = [ | ||
228 | 196 | ('index', 'pint.tex', 'pint Documentation', | ||
229 | 197 | 'Hernan E. Grecco', 'manual'), | ||
230 | 198 | ] | ||
231 | 199 | |||
232 | 200 | # The name of an image file (relative to this directory) to place at the top of | ||
233 | 201 | # the title page. | ||
234 | 202 | #latex_logo = None | ||
235 | 203 | |||
236 | 204 | # For "manual" documents, if this is true, then toplevel headings are parts, | ||
237 | 205 | # not chapters. | ||
238 | 206 | #latex_use_parts = False | ||
239 | 207 | |||
240 | 208 | # If true, show page references after internal links. | ||
241 | 209 | #latex_show_pagerefs = False | ||
242 | 210 | |||
243 | 211 | # If true, show URL addresses after external links. | ||
244 | 212 | #latex_show_urls = False | ||
245 | 213 | |||
246 | 214 | # Documents to append as an appendix to all manuals. | ||
247 | 215 | #latex_appendices = [] | ||
248 | 216 | |||
249 | 217 | # If false, no module index is generated. | ||
250 | 218 | #latex_domain_indices = True | ||
251 | 219 | |||
252 | 220 | |||
253 | 221 | # -- Options for manual page output -------------------------------------------- | ||
254 | 222 | |||
255 | 223 | # One entry per manual page. List of tuples | ||
256 | 224 | # (source start file, name, description, authors, manual section). | ||
257 | 225 | man_pages = [ | ||
258 | 226 | ('index', 'pint', 'pint Documentation', | ||
259 | 227 | ['Hernan E. Grecco'], 1) | ||
260 | 228 | ] | ||
261 | 229 | |||
262 | 230 | # If true, show URL addresses after external links. | ||
263 | 231 | #man_show_urls = False | ||
264 | 232 | |||
265 | 233 | |||
266 | 234 | # -- Options for Texinfo output ------------------------------------------------ | ||
267 | 235 | |||
268 | 236 | # Grouping the document tree into Texinfo files. List of tuples | ||
269 | 237 | # (source start file, target name, title, author, | ||
270 | 238 | # dir menu entry, description, category) | ||
271 | 239 | texinfo_documents = [ | ||
272 | 240 | ('index', 'pint', 'pint Documentation', | ||
273 | 241 | 'Hernan E. Grecco', 'pint', 'One line description of project.', | ||
274 | 242 | 'Miscellaneous'), | ||
275 | 243 | ] | ||
276 | 244 | |||
277 | 245 | # Documents to append as an appendix to all manuals. | ||
278 | 246 | #texinfo_appendices = [] | ||
279 | 247 | |||
280 | 248 | # If false, no module index is generated. | ||
281 | 249 | #texinfo_domain_indices = True | ||
282 | 250 | |||
283 | 251 | # How to display URL addresses: 'footnote', 'no', or 'inline'. | ||
284 | 252 | #texinfo_show_urls = 'footnote' | ||
285 | 253 | |||
286 | 254 | |||
287 | 255 | # -- Options for Epub output --------------------------------------------------- | ||
288 | 256 | |||
289 | 257 | # Bibliographic Dublin Core info. | ||
290 | 258 | epub_title = project | ||
291 | 259 | epub_author = author | ||
292 | 260 | epub_publisher = author | ||
293 | 261 | epub_copyright = copyright | ||
294 | 262 | |||
295 | 263 | # The language of the text. It defaults to the language option | ||
296 | 264 | # or en if the language is not set. | ||
297 | 265 | #epub_language = '' | ||
298 | 266 | |||
299 | 267 | # The scheme of the identifier. Typical schemes are ISBN or URL. | ||
300 | 268 | #epub_scheme = '' | ||
301 | 269 | |||
302 | 270 | # The unique identifier of the text. This can be a ISBN number | ||
303 | 271 | # or the project homepage. | ||
304 | 272 | #epub_identifier = '' | ||
305 | 273 | |||
306 | 274 | # A unique identification for the text. | ||
307 | 275 | #epub_uid = '' | ||
308 | 276 | |||
309 | 277 | # A tuple containing the cover image and cover page html template filenames. | ||
310 | 278 | #epub_cover = () | ||
311 | 279 | |||
312 | 280 | # HTML files that should be inserted before the pages created by sphinx. | ||
313 | 281 | # The format is a list of tuples containing the path and title. | ||
314 | 282 | #epub_pre_files = [] | ||
315 | 283 | |||
316 | 284 | # HTML files shat should be inserted after the pages created by sphinx. | ||
317 | 285 | # The format is a list of tuples containing the path and title. | ||
318 | 286 | #epub_post_files = [] | ||
319 | 287 | |||
320 | 288 | # A list of files that should not be packed into the epub file. | ||
321 | 289 | #epub_exclude_files = [] | ||
322 | 290 | |||
323 | 291 | # The depth of the table of contents in toc.ncx. | ||
324 | 292 | #epub_tocdepth = 3 | ||
325 | 293 | |||
326 | 294 | # Allow duplicate toc entries. | ||
327 | 295 | #epub_tocdup = True | ||
328 | 296 | |||
329 | 297 | |||
330 | 298 | # Example configuration for intersphinx: refer to the Python standard library. | ||
331 | 299 | intersphinx_mapping = {'http://docs.python.org/': None} | ||
332 | 300 | 0 | ||
333 | === removed directory '.pc/removes-privacy-breach-in-doc.patch' | |||
334 | === removed directory '.pc/removes-privacy-breach-in-doc.patch/docs' | |||
335 | === removed directory '.pc/removes-privacy-breach-in-doc.patch/docs/_themes' | |||
336 | === removed directory '.pc/removes-privacy-breach-in-doc.patch/docs/_themes/flask' | |||
337 | === removed file '.pc/removes-privacy-breach-in-doc.patch/docs/_themes/flask/layout.html' | |||
338 | --- .pc/removes-privacy-breach-in-doc.patch/docs/_themes/flask/layout.html 2014-09-05 23:26:05 +0000 | |||
339 | +++ .pc/removes-privacy-breach-in-doc.patch/docs/_themes/flask/layout.html 1970-01-01 00:00:00 +0000 | |||
340 | @@ -1,30 +0,0 @@ | |||
341 | 1 | {%- extends "basic/layout.html" %} | ||
342 | 2 | {%- block extrahead %} | ||
343 | 3 | {{ super() }} | ||
344 | 4 | {% if theme_touch_icon %} | ||
345 | 5 | <link rel="apple-touch-icon" href="{{ pathto('_static/' ~ theme_touch_icon, 1) }}" /> | ||
346 | 6 | {% endif %} | ||
347 | 7 | <link media="only screen and (max-device-width: 480px)" href="{{ | ||
348 | 8 | pathto('_static/small_flask.css', 1) }}" type= "text/css" rel="stylesheet" /> | ||
349 | 9 | {% endblock %} | ||
350 | 10 | {%- block relbar2 %} | ||
351 | 11 | {% if theme_github_fork %} | ||
352 | 12 | <a href="http://github.com/{{ theme_github_fork }}"><img style="position: fixed; top: 0; right: 0; border: 0;" | ||
353 | 13 | src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a> | ||
354 | 14 | {% endif %} | ||
355 | 15 | {% endblock %} | ||
356 | 16 | {% block header %} | ||
357 | 17 | {{ super() }} | ||
358 | 18 | {% if pagename == 'index' %} | ||
359 | 19 | <div> | ||
360 | 20 | {% endif %} | ||
361 | 21 | {% endblock %} | ||
362 | 22 | {%- block footer %} | ||
363 | 23 | <div class="footer"> | ||
364 | 24 | © Copyright {{ copyright }}. Pint {{ version }}. | ||
365 | 25 | Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>. | ||
366 | 26 | </div> | ||
367 | 27 | {% if pagename == 'index' %} | ||
368 | 28 | </div> | ||
369 | 29 | {% endif %} | ||
370 | 30 | {%- endblock %} | ||
371 | 31 | 0 | ||
372 | === removed file '.pc/removes-privacy-breach-in-doc.patch/docs/conf.py' | |||
373 | --- .pc/removes-privacy-breach-in-doc.patch/docs/conf.py 2014-09-05 23:26:05 +0000 | |||
374 | +++ .pc/removes-privacy-breach-in-doc.patch/docs/conf.py 1970-01-01 00:00:00 +0000 | |||
375 | @@ -1,299 +0,0 @@ | |||
376 | 1 | #!/usr/bin/env python3 | ||
377 | 2 | # -*- coding: utf-8 -*- | ||
378 | 3 | # | ||
379 | 4 | # pint documentation build configuration file, created by | ||
380 | 5 | # sphinx-quickstart on Thu Mar 1 13:33:14 2012. | ||
381 | 6 | # | ||
382 | 7 | # This file is execfile()d with the current directory set to its containing dir. | ||
383 | 8 | # | ||
384 | 9 | # Note that not all possible configuration values are present in this | ||
385 | 10 | # autogenerated file. | ||
386 | 11 | # | ||
387 | 12 | # All configuration values have a default; values that are commented out | ||
388 | 13 | # serve to show the default. | ||
389 | 14 | |||
390 | 15 | import sys, os | ||
391 | 16 | import pkg_resources | ||
392 | 17 | import datetime | ||
393 | 18 | |||
394 | 19 | # If extensions (or modules to document with autodoc) are in another directory, | ||
395 | 20 | # add these directories to sys.path here. If the directory is relative to the | ||
396 | 21 | # documentation root, use os.path.abspath to make it absolute, like shown here. | ||
397 | 22 | #sys.path.insert(0, os.path.abspath('.')) | ||
398 | 23 | |||
399 | 24 | # -- General configuration ----------------------------------------------------- | ||
400 | 25 | |||
401 | 26 | # If your documentation needs a minimal Sphinx version, state it here. | ||
402 | 27 | #needs_sphinx = '1.0' | ||
403 | 28 | |||
404 | 29 | # Add any Sphinx extension module names here, as strings. They can be extensions | ||
405 | 30 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. | ||
406 | 31 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.coverage', 'sphinx.ext.viewcode', 'sphinx.ext.mathjax'] | ||
407 | 32 | |||
408 | 33 | # Add any paths that contain templates here, relative to this directory. | ||
409 | 34 | templates_path = ['_templates'] | ||
410 | 35 | |||
411 | 36 | # The suffix of source filenames. | ||
412 | 37 | source_suffix = '.rst' | ||
413 | 38 | |||
414 | 39 | # The encoding of source files. | ||
415 | 40 | #source_encoding = 'utf-8-sig' | ||
416 | 41 | |||
417 | 42 | # The master toctree document. | ||
418 | 43 | master_doc = 'index' | ||
419 | 44 | |||
420 | 45 | # General information about the project. | ||
421 | 46 | project = 'pint' | ||
422 | 47 | author = 'Hernan E. Grecco' | ||
423 | 48 | |||
424 | 49 | # The version info for the project you're documenting, acts as replacement for | ||
425 | 50 | # |version| and |release|, also used in various other places throughout the | ||
426 | 51 | # built documents. | ||
427 | 52 | |||
428 | 53 | version = pkg_resources.get_distribution(project).version | ||
429 | 54 | release = version | ||
430 | 55 | this_year = datetime.date.today().year | ||
431 | 56 | copyright = '%s, %s' % (this_year, author) | ||
432 | 57 | |||
433 | 58 | # The language for content autogenerated by Sphinx. Refer to documentation | ||
434 | 59 | # for a list of supported languages. | ||
435 | 60 | #language = None | ||
436 | 61 | |||
437 | 62 | # There are two options for replacing |today|: either, you set today to some | ||
438 | 63 | # non-false value, then it is used: | ||
439 | 64 | #today = '' | ||
440 | 65 | # Else, today_fmt is used as the format for a strftime call. | ||
441 | 66 | #today_fmt = '%B %d, %Y' | ||
442 | 67 | |||
443 | 68 | # List of patterns, relative to source directory, that match files and | ||
444 | 69 | # directories to ignore when looking for source files. | ||
445 | 70 | exclude_patterns = ['_build'] | ||
446 | 71 | |||
447 | 72 | # The reST default role (used for this markup: `text`) to use for all documents. | ||
448 | 73 | #default_role = None | ||
449 | 74 | |||
450 | 75 | # If true, '()' will be appended to :func: etc. cross-reference text. | ||
451 | 76 | #add_function_parentheses = True | ||
452 | 77 | |||
453 | 78 | # If true, the current module name will be prepended to all description | ||
454 | 79 | # unit titles (such as .. function::). | ||
455 | 80 | #add_module_names = True | ||
456 | 81 | |||
457 | 82 | # If true, sectionauthor and moduleauthor directives will be shown in the | ||
458 | 83 | # output. They are ignored by default. | ||
459 | 84 | #show_authors = False | ||
460 | 85 | |||
461 | 86 | # The name of the Pygments (syntax highlighting) style to use. | ||
462 | 87 | pygments_style = 'sphinx' | ||
463 | 88 | |||
464 | 89 | # A list of ignored prefixes for module index sorting. | ||
465 | 90 | #modindex_common_prefix = [] | ||
466 | 91 | |||
467 | 92 | |||
468 | 93 | # -- Options for HTML output --------------------------------------------------- | ||
469 | 94 | |||
470 | 95 | # The theme to use for HTML and HTML Help pages. See the documentation for | ||
471 | 96 | # a list of builtin themes. | ||
472 | 97 | #html_theme = 'default' | ||
473 | 98 | html_theme = 'flask' | ||
474 | 99 | |||
475 | 100 | # Theme options are theme-specific and customize the look and feel of a theme | ||
476 | 101 | # further. For a list of options available for each theme, see the | ||
477 | 102 | # documentation. | ||
478 | 103 | #html_theme_options = {} | ||
479 | 104 | |||
480 | 105 | # Add any paths that contain custom themes here, relative to this directory. | ||
481 | 106 | #html_theme_path = [] | ||
482 | 107 | html_theme_path = ['_themes'] | ||
483 | 108 | |||
484 | 109 | # The name for this set of Sphinx documents. If None, it defaults to | ||
485 | 110 | # "<project> v<release> documentation". | ||
486 | 111 | #html_title = None | ||
487 | 112 | |||
488 | 113 | # A shorter title for the navigation bar. Default is the same as html_title. | ||
489 | 114 | #html_short_title = None | ||
490 | 115 | |||
491 | 116 | # The name of an image file (relative to this directory) to place at the top | ||
492 | 117 | # of the sidebar. | ||
493 | 118 | #html_logo = None | ||
494 | 119 | |||
495 | 120 | # The name of an image file (within the static path) to use as favicon of the | ||
496 | 121 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 | ||
497 | 122 | # pixels large. | ||
498 | 123 | #html_favicon = None | ||
499 | 124 | |||
500 | 125 | # Add any paths that contain custom static files (such as style sheets) here, | ||
501 | 126 | # relative to this directory. They are copied after the builtin static files, | ||
502 | 127 | # so a file named "default.css" will overwrite the builtin "default.css". | ||
503 | 128 | html_static_path = ['_static'] | ||
504 | 129 | |||
505 | 130 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, | ||
506 | 131 | # using the given strftime format. | ||
507 | 132 | #html_last_updated_fmt = '%b %d, %Y' | ||
508 | 133 | |||
509 | 134 | # If true, SmartyPants will be used to convert quotes and dashes to | ||
510 | 135 | # typographically correct entities. | ||
511 | 136 | #html_use_smartypants = True | ||
512 | 137 | |||
513 | 138 | # Custom sidebar templates, maps document names to template names. | ||
514 | 139 | #html_sidebars = {} | ||
515 | 140 | html_sidebars = { | ||
516 | 141 | 'index': ['sidebarintro.html', 'sourcelink.html', 'searchbox.html'], | ||
517 | 142 | '**': ['sidebarlogo.html', 'localtoc.html', 'relations.html', | ||
518 | 143 | 'sourcelink.html', 'searchbox.html'] | ||
519 | 144 | } | ||
520 | 145 | |||
521 | 146 | # Additional templates that should be rendered to pages, maps page names to | ||
522 | 147 | # template names. | ||
523 | 148 | #html_additional_pages = {} | ||
524 | 149 | |||
525 | 150 | # If false, no module index is generated. | ||
526 | 151 | #html_domain_indices = True | ||
527 | 152 | |||
528 | 153 | # If false, no index is generated. | ||
529 | 154 | #html_use_index = True | ||
530 | 155 | |||
531 | 156 | # If true, the index is split into individual pages for each letter. | ||
532 | 157 | #html_split_index = False | ||
533 | 158 | |||
534 | 159 | # If true, links to the reST sources are added to the pages. | ||
535 | 160 | #html_show_sourcelink = True | ||
536 | 161 | |||
537 | 162 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. | ||
538 | 163 | #html_show_sphinx = True | ||
539 | 164 | |||
540 | 165 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. | ||
541 | 166 | #html_show_copyright = True | ||
542 | 167 | |||
543 | 168 | # If true, an OpenSearch description file will be output, and all pages will | ||
544 | 169 | # contain a <link> tag referring to it. The value of this option must be the | ||
545 | 170 | # base URL from which the finished HTML is served. | ||
546 | 171 | #html_use_opensearch = '' | ||
547 | 172 | |||
548 | 173 | # This is the file name suffix for HTML files (e.g. ".xhtml"). | ||
549 | 174 | #html_file_suffix = None | ||
550 | 175 | |||
551 | 176 | # Output file base name for HTML help builder. | ||
552 | 177 | htmlhelp_basename = 'pintdoc' | ||
553 | 178 | |||
554 | 179 | |||
555 | 180 | # -- Options for LaTeX output -------------------------------------------------- | ||
556 | 181 | |||
557 | 182 | latex_elements = { | ||
558 | 183 | # The paper size ('letterpaper' or 'a4paper'). | ||
559 | 184 | #'papersize': 'letterpaper', | ||
560 | 185 | |||
561 | 186 | # The font size ('10pt', '11pt' or '12pt'). | ||
562 | 187 | #'pointsize': '10pt', | ||
563 | 188 | |||
564 | 189 | # Additional stuff for the LaTeX preamble. | ||
565 | 190 | #'preamble': '', | ||
566 | 191 | } | ||
567 | 192 | |||
568 | 193 | # Grouping the document tree into LaTeX files. List of tuples | ||
569 | 194 | # (source start file, target name, title, author, documentclass [howto/manual]). | ||
570 | 195 | latex_documents = [ | ||
571 | 196 | ('index', 'pint.tex', 'pint Documentation', | ||
572 | 197 | 'Hernan E. Grecco', 'manual'), | ||
573 | 198 | ] | ||
574 | 199 | |||
575 | 200 | # The name of an image file (relative to this directory) to place at the top of | ||
576 | 201 | # the title page. | ||
577 | 202 | #latex_logo = None | ||
578 | 203 | |||
579 | 204 | # For "manual" documents, if this is true, then toplevel headings are parts, | ||
580 | 205 | # not chapters. | ||
581 | 206 | #latex_use_parts = False | ||
582 | 207 | |||
583 | 208 | # If true, show page references after internal links. | ||
584 | 209 | #latex_show_pagerefs = False | ||
585 | 210 | |||
586 | 211 | # If true, show URL addresses after external links. | ||
587 | 212 | #latex_show_urls = False | ||
588 | 213 | |||
589 | 214 | # Documents to append as an appendix to all manuals. | ||
590 | 215 | #latex_appendices = [] | ||
591 | 216 | |||
592 | 217 | # If false, no module index is generated. | ||
593 | 218 | #latex_domain_indices = True | ||
594 | 219 | |||
595 | 220 | |||
596 | 221 | # -- Options for manual page output -------------------------------------------- | ||
597 | 222 | |||
598 | 223 | # One entry per manual page. List of tuples | ||
599 | 224 | # (source start file, name, description, authors, manual section). | ||
600 | 225 | man_pages = [ | ||
601 | 226 | ('index', 'pint', 'pint Documentation', | ||
602 | 227 | ['Hernan E. Grecco'], 1) | ||
603 | 228 | ] | ||
604 | 229 | |||
605 | 230 | # If true, show URL addresses after external links. | ||
606 | 231 | #man_show_urls = False | ||
607 | 232 | |||
608 | 233 | |||
609 | 234 | # -- Options for Texinfo output ------------------------------------------------ | ||
610 | 235 | |||
611 | 236 | # Grouping the document tree into Texinfo files. List of tuples | ||
612 | 237 | # (source start file, target name, title, author, | ||
613 | 238 | # dir menu entry, description, category) | ||
614 | 239 | texinfo_documents = [ | ||
615 | 240 | ('index', 'pint', 'pint Documentation', | ||
616 | 241 | 'Hernan E. Grecco', 'pint', 'One line description of project.', | ||
617 | 242 | 'Miscellaneous'), | ||
618 | 243 | ] | ||
619 | 244 | |||
620 | 245 | # Documents to append as an appendix to all manuals. | ||
621 | 246 | #texinfo_appendices = [] | ||
622 | 247 | |||
623 | 248 | # If false, no module index is generated. | ||
624 | 249 | #texinfo_domain_indices = True | ||
625 | 250 | |||
626 | 251 | # How to display URL addresses: 'footnote', 'no', or 'inline'. | ||
627 | 252 | #texinfo_show_urls = 'footnote' | ||
628 | 253 | |||
629 | 254 | |||
630 | 255 | # -- Options for Epub output --------------------------------------------------- | ||
631 | 256 | |||
632 | 257 | # Bibliographic Dublin Core info. | ||
633 | 258 | epub_title = project | ||
634 | 259 | epub_author = author | ||
635 | 260 | epub_publisher = author | ||
636 | 261 | epub_copyright = copyright | ||
637 | 262 | |||
638 | 263 | # The language of the text. It defaults to the language option | ||
639 | 264 | # or en if the language is not set. | ||
640 | 265 | #epub_language = '' | ||
641 | 266 | |||
642 | 267 | # The scheme of the identifier. Typical schemes are ISBN or URL. | ||
643 | 268 | #epub_scheme = '' | ||
644 | 269 | |||
645 | 270 | # The unique identifier of the text. This can be a ISBN number | ||
646 | 271 | # or the project homepage. | ||
647 | 272 | #epub_identifier = '' | ||
648 | 273 | |||
649 | 274 | # A unique identification for the text. | ||
650 | 275 | #epub_uid = '' | ||
651 | 276 | |||
652 | 277 | # A tuple containing the cover image and cover page html template filenames. | ||
653 | 278 | #epub_cover = () | ||
654 | 279 | |||
655 | 280 | # HTML files that should be inserted before the pages created by sphinx. | ||
656 | 281 | # The format is a list of tuples containing the path and title. | ||
657 | 282 | #epub_pre_files = [] | ||
658 | 283 | |||
659 | 284 | # HTML files shat should be inserted after the pages created by sphinx. | ||
660 | 285 | # The format is a list of tuples containing the path and title. | ||
661 | 286 | #epub_post_files = [] | ||
662 | 287 | |||
663 | 288 | # A list of files that should not be packed into the epub file. | ||
664 | 289 | #epub_exclude_files = [] | ||
665 | 290 | |||
666 | 291 | # The depth of the table of contents in toc.ncx. | ||
667 | 292 | #epub_tocdepth = 3 | ||
668 | 293 | |||
669 | 294 | # Allow duplicate toc entries. | ||
670 | 295 | #epub_tocdup = True | ||
671 | 296 | |||
672 | 297 | |||
673 | 298 | # Example configuration for intersphinx: refer to the Python standard library. | ||
674 | 299 | intersphinx_mapping = {'http://docs.python.org/': None} | ||
675 | 300 | 0 | ||
676 | === removed file '.travis.yml' | |||
677 | --- .travis.yml 2014-09-05 23:26:05 +0000 | |||
678 | +++ .travis.yml 1970-01-01 00:00:00 +0000 | |||
679 | @@ -1,65 +0,0 @@ | |||
680 | 1 | language: python | ||
681 | 2 | |||
682 | 3 | python: | ||
683 | 4 | - "2.6" | ||
684 | 5 | - "2.7" | ||
685 | 6 | - "3.2" | ||
686 | 7 | - "3.3" | ||
687 | 8 | - "3.4" | ||
688 | 9 | |||
689 | 10 | env: | ||
690 | 11 | - UNCERTAINTIES="N" NUMPY_VERSION=0 | ||
691 | 12 | - UNCERTAINTIES="N" NUMPY_VERSION=1.6.2 | ||
692 | 13 | - UNCERTAINTIES="N" NUMPY_VERSION=1.7.1 | ||
693 | 14 | - UNCERTAINTIES="N" NUMPY_VERSION=1.8.1 | ||
694 | 15 | - UNCERTAINTIES="Y" NUMPY_VERSION=0 | ||
695 | 16 | - UNCERTAINTIES="Y" NUMPY_VERSION=1.6.2 | ||
696 | 17 | - UNCERTAINTIES="Y" NUMPY_VERSION=1.7.1 | ||
697 | 18 | - UNCERTAINTIES="Y" NUMPY_VERSION=1.8.1 | ||
698 | 19 | |||
699 | 20 | branches: | ||
700 | 21 | only: | ||
701 | 22 | - master | ||
702 | 23 | - develop | ||
703 | 24 | |||
704 | 25 | before_install: | ||
705 | 26 | - wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh | ||
706 | 27 | - chmod +x miniconda.sh | ||
707 | 28 | - ./miniconda.sh -b | ||
708 | 29 | - export PATH=/home/travis/miniconda/bin:$PATH | ||
709 | 30 | - conda update --yes conda | ||
710 | 31 | |||
711 | 32 | # The next couple lines fix a crash with multiprocessing on Travis and are not specific to using Miniconda | ||
712 | 33 | - sudo rm -rf /dev/shm | ||
713 | 34 | - sudo ln -s /run/shm /dev/shm | ||
714 | 35 | |||
715 | 36 | install: | ||
716 | 37 | - conda create -c mwcraig --yes -n env_name python=$TRAVIS_PYTHON_VERSION pip | ||
717 | 38 | - source activate env_name | ||
718 | 39 | - if [ $TRAVIS_PYTHON_VERSION == '2.6' ]; then pip install unittest2; fi | ||
719 | 40 | - if [ $UNCERTAINTIES == 'Y' ]; then pip install uncertainties; fi | ||
720 | 41 | - if [ $NUMPY_VERSION != '0' ]; then conda install -c mwcraig --yes numpy==$NUMPY_VERSION; fi | ||
721 | 42 | - pip install coverage coveralls | ||
722 | 43 | |||
723 | 44 | script: | ||
724 | 45 | - coverage run -p --source=pint --omit="*test*","*compat*" setup.py test | ||
725 | 46 | - coverage combine | ||
726 | 47 | - coverage report -m | ||
727 | 48 | |||
728 | 49 | after_script: | ||
729 | 50 | - coveralls --verbose | ||
730 | 51 | |||
731 | 52 | matrix: | ||
732 | 53 | exclude: | ||
733 | 54 | - python: "3.3" | ||
734 | 55 | env: UNCERTAINTIES="Y" NUMPY_VERSION=1.6.2 | ||
735 | 56 | - python: "3.4" | ||
736 | 57 | env: UNCERTAINTIES="Y" NUMPY_VERSION=1.6.2 | ||
737 | 58 | - python: "3.4" | ||
738 | 59 | env: UNCERTAINTIES="Y" NUMPY_VERSION=1.7.1 | ||
739 | 60 | - python: "3.3" | ||
740 | 61 | env: UNCERTAINTIES="N" NUMPY_VERSION=1.6.2 | ||
741 | 62 | - python: "3.4" | ||
742 | 63 | env: UNCERTAINTIES="N" NUMPY_VERSION=1.6.2 | ||
743 | 64 | - python: "3.4" | ||
744 | 65 | env: UNCERTAINTIES="N" NUMPY_VERSION=1.7.1 | ||
745 | 66 | 0 | ||
746 | === modified file 'AUTHORS' | |||
747 | --- AUTHORS 2014-09-05 23:26:05 +0000 | |||
748 | +++ AUTHORS 2015-01-07 15:51:38 +0000 | |||
749 | @@ -5,9 +5,9 @@ | |||
750 | 5 | * Alexander Böhn <fish2000@gmail.com> | 5 | * Alexander Böhn <fish2000@gmail.com> |
751 | 6 | * Brend Wanders <b.wanders@utwente.nl> | 6 | * Brend Wanders <b.wanders@utwente.nl> |
752 | 7 | * choloepus | 7 | * choloepus |
753 | 8 | * coutinho <coutinho@esrf.fr> | ||
754 | 9 | * Daniel Sokolowski <daniel.sokolowski@danols.com> | 8 | * Daniel Sokolowski <daniel.sokolowski@danols.com> |
755 | 10 | * Dave Brooks <dave@bcs.co.nz> | 9 | * Dave Brooks <dave@bcs.co.nz> |
756 | 10 | * David Linke | ||
757 | 11 | * Eduard Bopp <eduard.bopp@aepsil0n.de> | 11 | * Eduard Bopp <eduard.bopp@aepsil0n.de> |
758 | 12 | * Felix Hummel <felix@felixhummel.de> | 12 | * Felix Hummel <felix@felixhummel.de> |
759 | 13 | * Giel van Schijndel <me@mortis.eu> | 13 | * Giel van Schijndel <me@mortis.eu> |
760 | @@ -15,11 +15,17 @@ | |||
761 | 15 | * Jim Turner <jturner314@gmail.com> | 15 | * Jim Turner <jturner314@gmail.com> |
762 | 16 | * Joel B. Mohler <joel@kiwistrawberry.us> | 16 | * Joel B. Mohler <joel@kiwistrawberry.us> |
763 | 17 | * John David Reaver <jdreaver@adlerhorst.com> | 17 | * John David Reaver <jdreaver@adlerhorst.com> |
764 | 18 | * Jonas Olson <jolson@kth.se> | ||
765 | 18 | * Kenneth D. Mankoff <mankoff@gmail.com> | 19 | * Kenneth D. Mankoff <mankoff@gmail.com> |
766 | 19 | * Luke Campbell <luke.s.campbell@gmail.com> | 20 | * Luke Campbell <luke.s.campbell@gmail.com> |
767 | 21 | * Matthieu Dartiailh <marul@laposte.net> | ||
768 | 20 | * Nate Bogdanowicz <natezb@gmail.com> | 22 | * Nate Bogdanowicz <natezb@gmail.com> |
769 | 21 | * Peter Grayson <jpgrayson@gmail.com> | 23 | * Peter Grayson <jpgrayson@gmail.com> |
770 | 22 | * Richard Barnes <rbarnes@umn.edu> | 24 | * Richard Barnes <rbarnes@umn.edu> |
771 | 25 | * Ryan Kingsbury <RyanSKingsbury@alumni.unc.edu> | ||
772 | 23 | * Sundar Raman <cybertoast@gmail.com> | 26 | * Sundar Raman <cybertoast@gmail.com> |
773 | 24 | * Tiago Coutinho <coutinho@esrf.fr> | 27 | * Tiago Coutinho <coutinho@esrf.fr> |
774 | 25 | * Tom Ritchford <tom@swirly.com> | 28 | * Tom Ritchford <tom@swirly.com> |
775 | 29 | * Virgil Dupras <virgil.dupras@savoirfairelinux.com> | ||
776 | 30 | |||
777 | 31 | (If you think that your name belongs here, please let the maintainer know) | ||
778 | 26 | 32 | ||
779 | === modified file 'CHANGES' | |||
780 | --- CHANGES 2014-09-05 23:26:05 +0000 | |||
781 | +++ CHANGES 2015-01-07 15:51:38 +0000 | |||
782 | @@ -2,6 +2,39 @@ | |||
783 | 2 | ============== | 2 | ============== |
784 | 3 | 3 | ||
785 | 4 | 4 | ||
786 | 5 | 0.6 (2014-11-07) | ||
787 | 6 | ---------------- | ||
788 | 7 | |||
789 | 8 | - Fix operations with measurments and user defined units. | ||
790 | 9 | (Issue #204) | ||
791 | 10 | - Faster conversions through caching and other performance improvements. | ||
792 | 11 | (Issue #193, thanks MatthieuDartiailh) | ||
793 | 12 | - Better error messages on Quantity.__setitem__. | ||
794 | 13 | (Issue #191) | ||
795 | 14 | - Fixed abbreviation of fluid_ounce. | ||
796 | 15 | (Issue #187, thanks hsoft) | ||
797 | 16 | - Defined Angstrom symbol. | ||
798 | 17 | (Issue #181, thanks JonasOlson) | ||
799 | 18 | - Removed fetching version from git repo as it triggers XCode installation on OSX. | ||
800 | 19 | (Issue #178, thanks deanishe) | ||
801 | 20 | - Improved context documentation. | ||
802 | 21 | (Issue #176 and 179, thanks rsking84) | ||
803 | 22 | - Added Chemistry context. | ||
804 | 23 | (Issue #179, thanks rsking84) | ||
805 | 24 | - Fix help(UnitRegisty) | ||
806 | 25 | (Issue #168) | ||
807 | 26 | - Optimized "get_dimensionality" and "get_base_name". | ||
808 | 27 | (Issue #166 and #167, thanks jbmohler) | ||
809 | 28 | - Renamed ureg.parse_units parameter "to_delta" to "as_delta" to make clear. | ||
810 | 29 | that no conversion happens. Accordingly, the parameter/property | ||
811 | 30 | "default_to_delta" of UnitRegistry was renamed to "default_as_delta". | ||
812 | 31 | (Issue #158, thanks dalit) | ||
813 | 32 | - Fixed problem when adding two uncertainties. | ||
814 | 33 | (thanks dalito) | ||
815 | 34 | - Full support for Offset units (e.g. temperature) | ||
816 | 35 | (Issue #88, #143, #147 and #161, thanks dalito) | ||
817 | 36 | |||
818 | 37 | |||
819 | 5 | 0.5.2 (2014-07-31) | 38 | 0.5.2 (2014-07-31) |
820 | 6 | ------------------ | 39 | ------------------ |
821 | 7 | 40 | ||
822 | 8 | 41 | ||
823 | === added file 'CHANGES_DEV' | |||
824 | --- CHANGES_DEV 1970-01-01 00:00:00 +0000 | |||
825 | +++ CHANGES_DEV 2015-01-07 15:51:38 +0000 | |||
826 | @@ -0,0 +1,5 @@ | |||
827 | 1 | |||
828 | 2 | |||
829 | 3 | |||
830 | 4 | 0.7 (unreleased) | ||
831 | 5 | ---------------- | ||
832 | 0 | 6 | ||
833 | === modified file 'MANIFEST.in' | |||
834 | --- MANIFEST.in 2014-09-05 23:26:05 +0000 | |||
835 | +++ MANIFEST.in 2015-01-07 15:51:38 +0000 | |||
836 | @@ -1,4 +1,4 @@ | |||
838 | 1 | include README AUTHORS CHANGES LICENSE | 1 | include README AUTHORS CHANGES LICENSE CHANGES_DEV |
839 | 2 | recursive-include pint * | 2 | recursive-include pint * |
840 | 3 | recursive-include docs * | 3 | recursive-include docs * |
841 | 4 | recursive-include bench * | 4 | recursive-include bench * |
842 | 5 | 5 | ||
843 | === added file 'PKG-INFO' | |||
844 | --- PKG-INFO 1970-01-01 00:00:00 +0000 | |||
845 | +++ PKG-INFO 2015-01-07 15:51:38 +0000 | |||
846 | @@ -0,0 +1,400 @@ | |||
847 | 1 | Metadata-Version: 1.1 | ||
848 | 2 | Name: Pint | ||
849 | 3 | Version: 0.6 | ||
850 | 4 | Summary: Physical quantities module | ||
851 | 5 | Home-page: https://github.com/hgrecco/pint | ||
852 | 6 | Author: Hernan E. Grecco | ||
853 | 7 | Author-email: hernan.grecco@gmail.com | ||
854 | 8 | License: BSD | ||
855 | 9 | Description: Pint: a Python units library | ||
856 | 10 | ============================ | ||
857 | 11 | |||
858 | 12 | Pint is Python module/package to define, operate and manipulate physical | ||
859 | 13 | quantities: the product of a numerical value and a unit of measurement. | ||
860 | 14 | It allows arithmetic operations between them and conversions from and | ||
861 | 15 | to different units. | ||
862 | 16 | |||
863 | 17 | It is distributed with a comprehensive list of physical units, prefixes | ||
864 | 18 | and constants. Due to its modular design, you to extend (or even rewrite!) | ||
865 | 19 | the complete list without changing the source code. | ||
866 | 20 | |||
867 | 21 | It has a complete test coverage. It runs in Python 2.7 and 3.X | ||
868 | 22 | with no other dependency. It licensed under BSD. | ||
869 | 23 | |||
870 | 24 | |||
871 | 25 | Design principles | ||
872 | 26 | ----------------- | ||
873 | 27 | |||
874 | 28 | Although there are already a few very good Python packages to handle physical | ||
875 | 29 | quantities, no one was really fitting my needs. Like most developers, I programed | ||
876 | 30 | Pint to scratch my own itches. | ||
877 | 31 | |||
878 | 32 | - Unit parsing: prefixed and pluralized forms of units are recognized without | ||
879 | 33 | explicitly defining them. In other words: as the prefix *kilo* and the unit *meter* | ||
880 | 34 | are defined, Pint understands *kilometers*. This results in a much shorter and | ||
881 | 35 | maintainable unit definition list as compared to other packages. | ||
882 | 36 | |||
883 | 37 | - Standalone unit definitions: units definitions are loaded from simple and | ||
884 | 38 | easy to edit text file. Adding and changing units and their definitions does | ||
885 | 39 | not involve changing the code. | ||
886 | 40 | |||
887 | 41 | - Advanced string formatting: a quantity can be formatted into string using | ||
888 | 42 | PEP 3101 syntax. Extended conversion flags are given to provide latex and pretty | ||
889 | 43 | formatting. | ||
890 | 44 | |||
891 | 45 | - Small codebase: small and easy to maintain with a flat hierarchy. | ||
892 | 46 | |||
893 | 47 | - Dependency free: it depends only on Python and its standard library. | ||
894 | 48 | |||
895 | 49 | - Python 2 and 3: A single codebase that runs unchanged in Python 2.7+ and Python 3.0+. | ||
896 | 50 | |||
897 | 51 | - Advanced NumPy support: While NumPy is not a requirement for Pint, | ||
898 | 52 | when available ndarray methods and ufuncs can be used in Quantity objects. | ||
899 | 53 | |||
900 | 54 | |||
901 | 55 | Pint is written and maintained by Hernan E. Grecco <hernan.grecco@gmail.com>. | ||
902 | 56 | |||
903 | 57 | Other contributors, listed alphabetically, are: | ||
904 | 58 | |||
905 | 59 | * Alexander Böhn <fish2000@gmail.com> | ||
906 | 60 | * Brend Wanders <b.wanders@utwente.nl> | ||
907 | 61 | * choloepus | ||
908 | 62 | * Daniel Sokolowski <daniel.sokolowski@danols.com> | ||
909 | 63 | * Dave Brooks <dave@bcs.co.nz> | ||
910 | 64 | * David Linke | ||
911 | 65 | * Eduard Bopp <eduard.bopp@aepsil0n.de> | ||
912 | 66 | * Felix Hummel <felix@felixhummel.de> | ||
913 | 67 | * Giel van Schijndel <me@mortis.eu> | ||
914 | 68 | * James Rowe <jnrowe@gmail.com> | ||
915 | 69 | * Jim Turner <jturner314@gmail.com> | ||
916 | 70 | * Joel B. Mohler <joel@kiwistrawberry.us> | ||
917 | 71 | * John David Reaver <jdreaver@adlerhorst.com> | ||
918 | 72 | * Jonas Olson <jolson@kth.se> | ||
919 | 73 | * Kenneth D. Mankoff <mankoff@gmail.com> | ||
920 | 74 | * Luke Campbell <luke.s.campbell@gmail.com> | ||
921 | 75 | * Matthieu Dartiailh <marul@laposte.net> | ||
922 | 76 | * Nate Bogdanowicz <natezb@gmail.com> | ||
923 | 77 | * Peter Grayson <jpgrayson@gmail.com> | ||
924 | 78 | * Richard Barnes <rbarnes@umn.edu> | ||
925 | 79 | * Ryan Kingsbury <RyanSKingsbury@alumni.unc.edu> | ||
926 | 80 | * Sundar Raman <cybertoast@gmail.com> | ||
927 | 81 | * Tiago Coutinho <coutinho@esrf.fr> | ||
928 | 82 | * Tom Ritchford <tom@swirly.com> | ||
929 | 83 | * Virgil Dupras <virgil.dupras@savoirfairelinux.com> | ||
930 | 84 | |||
931 | 85 | (If you think that your name belongs here, please let the maintainer know) | ||
932 | 86 | |||
933 | 87 | |||
934 | 88 | Pint Changelog | ||
935 | 89 | ============== | ||
936 | 90 | |||
937 | 91 | |||
938 | 92 | 0.6 (2014-11-07) | ||
939 | 93 | ---------------- | ||
940 | 94 | |||
941 | 95 | - Fix operations with measurments and user defined units. | ||
942 | 96 | (Issue #204) | ||
943 | 97 | - Faster conversions through caching and other performance improvements. | ||
944 | 98 | (Issue #193, thanks MatthieuDartiailh) | ||
945 | 99 | - Better error messages on Quantity.__setitem__. | ||
946 | 100 | (Issue #191) | ||
947 | 101 | - Fixed abbreviation of fluid_ounce. | ||
948 | 102 | (Issue #187, thanks hsoft) | ||
949 | 103 | - Defined Angstrom symbol. | ||
950 | 104 | (Issue #181, thanks JonasOlson) | ||
951 | 105 | - Removed fetching version from git repo as it triggers XCode installation on OSX. | ||
952 | 106 | (Issue #178, thanks deanishe) | ||
953 | 107 | - Improved context documentation. | ||
954 | 108 | (Issue #176 and 179, thanks rsking84) | ||
955 | 109 | - Added Chemistry context. | ||
956 | 110 | (Issue #179, thanks rsking84) | ||
957 | 111 | - Fix help(UnitRegisty) | ||
958 | 112 | (Issue #168) | ||
959 | 113 | - Optimized "get_dimensionality" and "get_base_name". | ||
960 | 114 | (Issue #166 and #167, thanks jbmohler) | ||
961 | 115 | - Renamed ureg.parse_units parameter "to_delta" to "as_delta" to make clear. | ||
962 | 116 | that no conversion happens. Accordingly, the parameter/property | ||
963 | 117 | "default_to_delta" of UnitRegistry was renamed to "default_as_delta". | ||
964 | 118 | (Issue #158, thanks dalit) | ||
965 | 119 | - Fixed problem when adding two uncertainties. | ||
966 | 120 | (thanks dalito) | ||
967 | 121 | - Full support for Offset units (e.g. temperature) | ||
968 | 122 | (Issue #88, #143, #147 and #161, thanks dalito) | ||
969 | 123 | |||
970 | 124 | |||
971 | 125 | 0.5.2 (2014-07-31) | ||
972 | 126 | ------------------ | ||
973 | 127 | |||
974 | 128 | - Changed travis config to use miniconda for faster testing. | ||
975 | 129 | - Added wheel configuration to setup.cfg. | ||
976 | 130 | - Ensure resource streams are closed after reading. | ||
977 | 131 | - Require setuptools. | ||
978 | 132 | (Issue #169) | ||
979 | 133 | - Implemented real, imag and T Quantity properties. | ||
980 | 134 | (Issue #171) | ||
981 | 135 | - Implemented __int__ and __long__ for Quantity | ||
982 | 136 | (Issue #170) | ||
983 | 137 | - Fixed SI prefix error on ureg.convert. | ||
984 | 138 | (Issue #156, thanks jdreaver) | ||
985 | 139 | - Fixed parsing of multiparemeter contexts. | ||
986 | 140 | (Issue #174) | ||
987 | 141 | |||
988 | 142 | |||
989 | 143 | 0.5.1 (2014-06-03) | ||
990 | 144 | ------------------ | ||
991 | 145 | |||
992 | 146 | - Implemented a standard way to change the registry used in unpickling operations. | ||
993 | 147 | (Issue #148) | ||
994 | 148 | - Fix bug where conversion would fail due to caching. | ||
995 | 149 | (Issue #140, thanks jdreaver) | ||
996 | 150 | - Allow assigning Not a Number to a quantity array. | ||
997 | 151 | (Issue #127) | ||
998 | 152 | - Decoupled Quantity in place and not in place unit conversion methods. | ||
999 | 153 | - Return None in functions that modify quantities in place. | ||
1000 | 154 | - Improved testing infrastructure to check for unwanted warnings. | ||
1001 | 155 | - Added test function at the package level to run all tests. | ||
1002 | 156 | |||
1003 | 157 | |||
1004 | 158 | 0.5 (2014-05-07) | ||
1005 | 159 | ---------------- | ||
1006 | 160 | |||
1007 | 161 | - Improved test suite helper functions. | ||
1008 | 162 | - Print honors default format w/o format(). | ||
1009 | 163 | (Issue #132, thanks mankoff) | ||
1010 | 164 | - Fixed sum() by treating number zero as a special case. | ||
1011 | 165 | (Issue #122, thanks rec) | ||
1012 | 166 | - Improved behaviour in ScaleConverter, OffsetConverter and Quantity.to. | ||
1013 | 167 | (Issue #120) | ||
1014 | 168 | - Reimplemented loading of default definitions to allow Pint in a cx_freeze or similar package. | ||
1015 | 169 | (Issue #118, thanks jbmohler) | ||
1016 | 170 | - Implemented parsing of pretty printed units. | ||
1017 | 171 | (Issue #117, thanks jpgrayson) | ||
1018 | 172 | - Fixed representation of dimensionless quantities. | ||
1019 | 173 | (Issue #112, thanks rec) | ||
1020 | 174 | - Raise error when invalid formatting code is given. | ||
1021 | 175 | (Issue #111, thanks rec) | ||
1022 | 176 | - Default registry to lazy load, raise error on redefinition | ||
1023 | 177 | (Issue #108, thanks rec, aepsil0n) | ||
1024 | 178 | - Added condensed format. | ||
1025 | 179 | (Issue #107, thanks rec) | ||
1026 | 180 | - Added UnitRegistry () operator to parse expression replacing []. | ||
1027 | 181 | (Issue #106, thanks rec) | ||
1028 | 182 | - Optional case insensitive unit parsing. | ||
1029 | 183 | (Issue #105, thanks rec, jeremyfreeman, dbrnz) | ||
1030 | 184 | - Change the Quantity mutability depending on magnitude type. | ||
1031 | 185 | (Issue #104, thanks rec) | ||
1032 | 186 | - Implemented API to list compatible units. | ||
1033 | 187 | (Issue #89) | ||
1034 | 188 | - Implemented cache of key UnitRegistry methods. | ||
1035 | 189 | - Rewrote the Measurement class to use uncertainties. | ||
1036 | 190 | (Issue #24) | ||
1037 | 191 | |||
1038 | 192 | |||
1039 | 193 | 0.4.2 (2014-02-14) | ||
1040 | 194 | ------------------ | ||
1041 | 195 | |||
1042 | 196 | - Python 2.6 support | ||
1043 | 197 | (Issue #96, thanks tiagocoutinho) | ||
1044 | 198 | - Fixed symbol for inch. | ||
1045 | 199 | (Issue #102, thanks cybertoast) | ||
1046 | 200 | - Stop raising AttributeError when wrapping funcs without all of the attributes. | ||
1047 | 201 | (Issue #100, thanks jturner314) | ||
1048 | 202 | - Fixed warning appearing in Py2.x when comparing a Numpy Array with an empty string. | ||
1049 | 203 | (Issue #98, thanks jturner314) | ||
1050 | 204 | - Add links to AUR packages in docs. | ||
1051 | 205 | (Issue #91, thanks jturner314) | ||
1052 | 206 | - Fixed garbage collection related problem. | ||
1053 | 207 | (Issue #92, thanks jturner314) | ||
1054 | 208 | |||
1055 | 209 | |||
1056 | 210 | 0.4.1 (2014-01-12) | ||
1057 | 211 | ------------------ | ||
1058 | 212 | |||
1059 | 213 | - Integer Division with Arrays. | ||
1060 | 214 | (Issue #80, thanks jdreaver) | ||
1061 | 215 | - Improved Documentation. | ||
1062 | 216 | (Issue #83, thanks choloepus) | ||
1063 | 217 | - Removed 'h' alias for hour due to conflict with Planck's constant. | ||
1064 | 218 | (Issue #82, thanks choloepus) | ||
1065 | 219 | - Improved get_base_units for non-multiplicative units. | ||
1066 | 220 | (Issue #85, thanks exxus) | ||
1067 | 221 | - Refactored code for multiplication. | ||
1068 | 222 | (Issue #84, thanks jturner314) | ||
1069 | 223 | - Removed 'R' alias for roentgen as it collides with molar_gas_constant. | ||
1070 | 224 | (Issue #87, thanks rsking84) | ||
1071 | 225 | - Improved naming of temperature units and multiplication of non-multiplicative units. | ||
1072 | 226 | (Issue #86, tahsnk exxus) | ||
1073 | 227 | |||
1074 | 228 | |||
1075 | 229 | |||
1076 | 230 | 0.4 (2013-12-17) | ||
1077 | 231 | ---------------- | ||
1078 | 232 | |||
1079 | 233 | - Introduced Contexts: relation between incompatible dimensions. | ||
1080 | 234 | (Issue #65) | ||
1081 | 235 | - Fixed get_base_units for non multiplicative units. | ||
1082 | 236 | (Related to issue #66) | ||
1083 | 237 | - Implemented default formatting for quantities. | ||
1084 | 238 | - Changed comparison between Quantities containing NumPy arrays. | ||
1085 | 239 | (Issue #75) - BACKWARDS INCOMPATIBLE CHANGE | ||
1086 | 240 | - Fixes for NumPy 1.8 due to changes in handling binary ops. | ||
1087 | 241 | (Issue #73) | ||
1088 | 242 | |||
1089 | 243 | |||
1090 | 244 | 0.3.3 (2013-11-29) | ||
1091 | 245 | ------------------ | ||
1092 | 246 | |||
1093 | 247 | - ParseHelper can now parse units named like python keywords. | ||
1094 | 248 | (Issue #69) | ||
1095 | 249 | - Fix comparison of quantities. | ||
1096 | 250 | (Issue #74) | ||
1097 | 251 | - Fix Inequality operator. | ||
1098 | 252 | (Issue #70, thanks muggenhor) | ||
1099 | 253 | - Improved travis configuration. | ||
1100 | 254 | (thanks muggenhor) | ||
1101 | 255 | |||
1102 | 256 | |||
1103 | 257 | 0.3.2 (2013-10-22) | ||
1104 | 258 | ------------------ | ||
1105 | 259 | |||
1106 | 260 | - Fix get_dimensionality for non multiplicative units. | ||
1107 | 261 | (Issue #66) | ||
1108 | 262 | - Proper handling of @import directive inside a file read using pkg_resources. | ||
1109 | 263 | (Issue #68) | ||
1110 | 264 | |||
1111 | 265 | |||
1112 | 266 | 0.3.1 (2013-09-15) | ||
1113 | 267 | ------------------ | ||
1114 | 268 | |||
1115 | 269 | - fix right division on python 2.7 | ||
1116 | 270 | (Issue #58, thanks natezb) | ||
1117 | 271 | - fix formatting of fractional exponentials between 0 and 1. | ||
1118 | 272 | (Issue #62, thanks jdreaver) | ||
1119 | 273 | - fix installation as egg. | ||
1120 | 274 | (Issue #61) | ||
1121 | 275 | - fix handling of strange values as input of Quantity. | ||
1122 | 276 | (Issue #53) | ||
1123 | 277 | - math operations between quantities of different registries now raise a ValueError. | ||
1124 | 278 | (Issue #52) | ||
1125 | 279 | |||
1126 | 280 | |||
1127 | 281 | 0.3 (2013-09-02) | ||
1128 | 282 | ---------------- | ||
1129 | 283 | |||
1130 | 284 | - support for IPython autocomplete and rich display. | ||
1131 | 285 | (Issues #30 and #31) | ||
1132 | 286 | - support for @import directive in definitions file. | ||
1133 | 287 | (Issue #22) | ||
1134 | 288 | - support for wrapping functions to make them pint-aware. | ||
1135 | 289 | (Issue #16) | ||
1136 | 290 | - support for comparing UnitsContainer to string. | ||
1137 | 291 | (Issue #35) | ||
1138 | 292 | - fix error raised while converting from a single unit to one expressed as | ||
1139 | 293 | the relation between many. | ||
1140 | 294 | (Issue #29) | ||
1141 | 295 | - fix error raised when unit symbol is missing. | ||
1142 | 296 | (Issue #41) | ||
1143 | 297 | - fix error raised when magnitude is Decimal. | ||
1144 | 298 | (Issue #46, thanks danielsokolowski) | ||
1145 | 299 | - support for non-installed pint. | ||
1146 | 300 | (Issue #42, thanks danielsokolowski) | ||
1147 | 301 | - support for application of numpy function on non-ndarray magnitudes. | ||
1148 | 302 | (Issue #44) | ||
1149 | 303 | - support for math operations on dimensionless Quantities (written with units). | ||
1150 | 304 | (Issue #45) | ||
1151 | 305 | - fix obtaining dimensionless quantity from string. | ||
1152 | 306 | (Issue #50) | ||
1153 | 307 | - fix adding and comparing numbers to a dimensionless quantity (written with units). | ||
1154 | 308 | (Issue #54) | ||
1155 | 309 | - Support for iter in Quantity. | ||
1156 | 310 | (Issue #55, thanks natezb) | ||
1157 | 311 | |||
1158 | 312 | |||
1159 | 313 | 0.2.1 (2013-07-02) | ||
1160 | 314 | ------------------ | ||
1161 | 315 | |||
1162 | 316 | - fix error raised while converting from a single unit to one expressed as | ||
1163 | 317 | the relation between many. | ||
1164 | 318 | (Issue #29) | ||
1165 | 319 | |||
1166 | 320 | |||
1167 | 321 | 0.2 (2013-05-13) | ||
1168 | 322 | ---------------- | ||
1169 | 323 | |||
1170 | 324 | - support for Measurement (Quantity +/- error). | ||
1171 | 325 | - implemented buckingham pi theorem for dimensional analysis. | ||
1172 | 326 | - support for temperature units and temperature difference units. | ||
1173 | 327 | - parser can infers if the user mean temperature or temperature difference. | ||
1174 | 328 | - support for derived dimensions (e.g. [speed] = [length] / [time]). | ||
1175 | 329 | - refactored the code into multiple files. | ||
1176 | 330 | - refactored code to isolate definitions and converters. | ||
1177 | 331 | - refactored formatter out of UnitParser class. | ||
1178 | 332 | - added tox and travis config files for CI. | ||
1179 | 333 | - comprehensive NumPy testing including almost all ufuncs. | ||
1180 | 334 | - full NumPy support (features is not longer experimental). | ||
1181 | 335 | - fixed bug preventing from having independent registries. | ||
1182 | 336 | (Issue #10, thanks bwanders) | ||
1183 | 337 | - forces real division as default for Quantities. | ||
1184 | 338 | (Issue #7, thanks dbrnz) | ||
1185 | 339 | - improved default unit definition file. | ||
1186 | 340 | (Issue #13, thanks r-barnes) | ||
1187 | 341 | - smarter parser supporting spaces as multiplications and other nice features. | ||
1188 | 342 | (Issue #13, thanks r-barnes) | ||
1189 | 343 | - moved testsuite inside package. | ||
1190 | 344 | - short forms of binary prefixes, more units and fix to less than comparison. | ||
1191 | 345 | (Issue #20, thanks muggenhor) | ||
1192 | 346 | - pint is now zip-safe | ||
1193 | 347 | (Issue #23, thanks muggenhor) | ||
1194 | 348 | |||
1195 | 349 | |||
1196 | 350 | Version 0.1.3 (2013-01-07) | ||
1197 | 351 | -------------------------- | ||
1198 | 352 | |||
1199 | 353 | - abbreviated quantity string formating. | ||
1200 | 354 | - complete Python 2.7 compatibility. | ||
1201 | 355 | - implemented pickle support for Quantities objects. | ||
1202 | 356 | - extended NumPy support. | ||
1203 | 357 | - various bugfixes. | ||
1204 | 358 | |||
1205 | 359 | |||
1206 | 360 | Version 0.1.2 (2012-08-12) | ||
1207 | 361 | -------------------------- | ||
1208 | 362 | |||
1209 | 363 | - experimenal NumPy support. | ||
1210 | 364 | - included default unit definitions file. | ||
1211 | 365 | (Issue #1, thanks fish2000) | ||
1212 | 366 | - better testing. | ||
1213 | 367 | - various bugfixes. | ||
1214 | 368 | - fixed some units definitions. | ||
1215 | 369 | (Issue #4, thanks craigholm) | ||
1216 | 370 | |||
1217 | 371 | |||
1218 | 372 | Version 0.1.1 (2012-07-31) | ||
1219 | 373 | -------------------------- | ||
1220 | 374 | |||
1221 | 375 | - better packaging and installation. | ||
1222 | 376 | |||
1223 | 377 | |||
1224 | 378 | Version 0.1 (2012-07-26) | ||
1225 | 379 | -------------------------- | ||
1226 | 380 | |||
1227 | 381 | - first public release. | ||
1228 | 382 | |||
1229 | 383 | Keywords: physical quantities unit conversion science | ||
1230 | 384 | Platform: UNKNOWN | ||
1231 | 385 | Classifier: Development Status :: 4 - Beta | ||
1232 | 386 | Classifier: Intended Audience :: Developers | ||
1233 | 387 | Classifier: Intended Audience :: Science/Research | ||
1234 | 388 | Classifier: License :: OSI Approved :: BSD License | ||
1235 | 389 | Classifier: Operating System :: MacOS :: MacOS X | ||
1236 | 390 | Classifier: Operating System :: Microsoft :: Windows | ||
1237 | 391 | Classifier: Operating System :: POSIX | ||
1238 | 392 | Classifier: Programming Language :: Python | ||
1239 | 393 | Classifier: Topic :: Scientific/Engineering | ||
1240 | 394 | Classifier: Topic :: Software Development :: Libraries | ||
1241 | 395 | Classifier: Programming Language :: Python :: 2.6 | ||
1242 | 396 | Classifier: Programming Language :: Python :: 2.7 | ||
1243 | 397 | Classifier: Programming Language :: Python :: 3.0 | ||
1244 | 398 | Classifier: Programming Language :: Python :: 3.1 | ||
1245 | 399 | Classifier: Programming Language :: Python :: 3.2 | ||
1246 | 400 | Classifier: Programming Language :: Python :: 3.3 | ||
1247 | 0 | 401 | ||
1248 | === added directory 'Pint.egg-info' | |||
1249 | === added file 'Pint.egg-info/PKG-INFO' | |||
1250 | --- Pint.egg-info/PKG-INFO 1970-01-01 00:00:00 +0000 | |||
1251 | +++ Pint.egg-info/PKG-INFO 2015-01-07 15:51:38 +0000 | |||
1252 | @@ -0,0 +1,400 @@ | |||
1253 | 1 | Metadata-Version: 1.1 | ||
1254 | 2 | Name: Pint | ||
1255 | 3 | Version: 0.6 | ||
1256 | 4 | Summary: Physical quantities module | ||
1257 | 5 | Home-page: https://github.com/hgrecco/pint | ||
1258 | 6 | Author: Hernan E. Grecco | ||
1259 | 7 | Author-email: hernan.grecco@gmail.com | ||
1260 | 8 | License: BSD | ||
1261 | 9 | Description: Pint: a Python units library | ||
1262 | 10 | ============================ | ||
1263 | 11 | |||
1264 | 12 | Pint is Python module/package to define, operate and manipulate physical | ||
1265 | 13 | quantities: the product of a numerical value and a unit of measurement. | ||
1266 | 14 | It allows arithmetic operations between them and conversions from and | ||
1267 | 15 | to different units. | ||
1268 | 16 | |||
1269 | 17 | It is distributed with a comprehensive list of physical units, prefixes | ||
1270 | 18 | and constants. Due to its modular design, you to extend (or even rewrite!) | ||
1271 | 19 | the complete list without changing the source code. | ||
1272 | 20 | |||
1273 | 21 | It has a complete test coverage. It runs in Python 2.7 and 3.X | ||
1274 | 22 | with no other dependency. It licensed under BSD. | ||
1275 | 23 | |||
1276 | 24 | |||
1277 | 25 | Design principles | ||
1278 | 26 | ----------------- | ||
1279 | 27 | |||
1280 | 28 | Although there are already a few very good Python packages to handle physical | ||
1281 | 29 | quantities, no one was really fitting my needs. Like most developers, I programed | ||
1282 | 30 | Pint to scratch my own itches. | ||
1283 | 31 | |||
1284 | 32 | - Unit parsing: prefixed and pluralized forms of units are recognized without | ||
1285 | 33 | explicitly defining them. In other words: as the prefix *kilo* and the unit *meter* | ||
1286 | 34 | are defined, Pint understands *kilometers*. This results in a much shorter and | ||
1287 | 35 | maintainable unit definition list as compared to other packages. | ||
1288 | 36 | |||
1289 | 37 | - Standalone unit definitions: units definitions are loaded from simple and | ||
1290 | 38 | easy to edit text file. Adding and changing units and their definitions does | ||
1291 | 39 | not involve changing the code. | ||
1292 | 40 | |||
1293 | 41 | - Advanced string formatting: a quantity can be formatted into string using | ||
1294 | 42 | PEP 3101 syntax. Extended conversion flags are given to provide latex and pretty | ||
1295 | 43 | formatting. | ||
1296 | 44 | |||
1297 | 45 | - Small codebase: small and easy to maintain with a flat hierarchy. | ||
1298 | 46 | |||
1299 | 47 | - Dependency free: it depends only on Python and its standard library. | ||
1300 | 48 | |||
1301 | 49 | - Python 2 and 3: A single codebase that runs unchanged in Python 2.7+ and Python 3.0+. | ||
1302 | 50 | |||
1303 | 51 | - Advanced NumPy support: While NumPy is not a requirement for Pint, | ||
1304 | 52 | when available ndarray methods and ufuncs can be used in Quantity objects. | ||
1305 | 53 | |||
1306 | 54 | |||
1307 | 55 | Pint is written and maintained by Hernan E. Grecco <hernan.grecco@gmail.com>. | ||
1308 | 56 | |||
1309 | 57 | Other contributors, listed alphabetically, are: | ||
1310 | 58 | |||
1311 | 59 | * Alexander Böhn <fish2000@gmail.com> | ||
1312 | 60 | * Brend Wanders <b.wanders@utwente.nl> | ||
1313 | 61 | * choloepus | ||
1314 | 62 | * Daniel Sokolowski <daniel.sokolowski@danols.com> | ||
1315 | 63 | * Dave Brooks <dave@bcs.co.nz> | ||
1316 | 64 | * David Linke | ||
1317 | 65 | * Eduard Bopp <eduard.bopp@aepsil0n.de> | ||
1318 | 66 | * Felix Hummel <felix@felixhummel.de> | ||
1319 | 67 | * Giel van Schijndel <me@mortis.eu> | ||
1320 | 68 | * James Rowe <jnrowe@gmail.com> | ||
1321 | 69 | * Jim Turner <jturner314@gmail.com> | ||
1322 | 70 | * Joel B. Mohler <joel@kiwistrawberry.us> | ||
1323 | 71 | * John David Reaver <jdreaver@adlerhorst.com> | ||
1324 | 72 | * Jonas Olson <jolson@kth.se> | ||
1325 | 73 | * Kenneth D. Mankoff <mankoff@gmail.com> | ||
1326 | 74 | * Luke Campbell <luke.s.campbell@gmail.com> | ||
1327 | 75 | * Matthieu Dartiailh <marul@laposte.net> | ||
1328 | 76 | * Nate Bogdanowicz <natezb@gmail.com> | ||
1329 | 77 | * Peter Grayson <jpgrayson@gmail.com> | ||
1330 | 78 | * Richard Barnes <rbarnes@umn.edu> | ||
1331 | 79 | * Ryan Kingsbury <RyanSKingsbury@alumni.unc.edu> | ||
1332 | 80 | * Sundar Raman <cybertoast@gmail.com> | ||
1333 | 81 | * Tiago Coutinho <coutinho@esrf.fr> | ||
1334 | 82 | * Tom Ritchford <tom@swirly.com> | ||
1335 | 83 | * Virgil Dupras <virgil.dupras@savoirfairelinux.com> | ||
1336 | 84 | |||
1337 | 85 | (If you think that your name belongs here, please let the maintainer know) | ||
1338 | 86 | |||
1339 | 87 | |||
1340 | 88 | Pint Changelog | ||
1341 | 89 | ============== | ||
1342 | 90 | |||
1343 | 91 | |||
1344 | 92 | 0.6 (2014-11-07) | ||
1345 | 93 | ---------------- | ||
1346 | 94 | |||
1347 | 95 | - Fix operations with measurments and user defined units. | ||
1348 | 96 | (Issue #204) | ||
1349 | 97 | - Faster conversions through caching and other performance improvements. | ||
1350 | 98 | (Issue #193, thanks MatthieuDartiailh) | ||
1351 | 99 | - Better error messages on Quantity.__setitem__. | ||
1352 | 100 | (Issue #191) | ||
1353 | 101 | - Fixed abbreviation of fluid_ounce. | ||
1354 | 102 | (Issue #187, thanks hsoft) | ||
1355 | 103 | - Defined Angstrom symbol. | ||
1356 | 104 | (Issue #181, thanks JonasOlson) | ||
1357 | 105 | - Removed fetching version from git repo as it triggers XCode installation on OSX. | ||
1358 | 106 | (Issue #178, thanks deanishe) | ||
1359 | 107 | - Improved context documentation. | ||
1360 | 108 | (Issue #176 and 179, thanks rsking84) | ||
1361 | 109 | - Added Chemistry context. | ||
1362 | 110 | (Issue #179, thanks rsking84) | ||
1363 | 111 | - Fix help(UnitRegisty) | ||
1364 | 112 | (Issue #168) | ||
1365 | 113 | - Optimized "get_dimensionality" and "get_base_name". | ||
1366 | 114 | (Issue #166 and #167, thanks jbmohler) | ||
1367 | 115 | - Renamed ureg.parse_units parameter "to_delta" to "as_delta" to make clear. | ||
1368 | 116 | that no conversion happens. Accordingly, the parameter/property | ||
1369 | 117 | "default_to_delta" of UnitRegistry was renamed to "default_as_delta". | ||
1370 | 118 | (Issue #158, thanks dalit) | ||
1371 | 119 | - Fixed problem when adding two uncertainties. | ||
1372 | 120 | (thanks dalito) | ||
1373 | 121 | - Full support for Offset units (e.g. temperature) | ||
1374 | 122 | (Issue #88, #143, #147 and #161, thanks dalito) | ||
1375 | 123 | |||
1376 | 124 | |||
1377 | 125 | 0.5.2 (2014-07-31) | ||
1378 | 126 | ------------------ | ||
1379 | 127 | |||
1380 | 128 | - Changed travis config to use miniconda for faster testing. | ||
1381 | 129 | - Added wheel configuration to setup.cfg. | ||
1382 | 130 | - Ensure resource streams are closed after reading. | ||
1383 | 131 | - Require setuptools. | ||
1384 | 132 | (Issue #169) | ||
1385 | 133 | - Implemented real, imag and T Quantity properties. | ||
1386 | 134 | (Issue #171) | ||
1387 | 135 | - Implemented __int__ and __long__ for Quantity | ||
1388 | 136 | (Issue #170) | ||
1389 | 137 | - Fixed SI prefix error on ureg.convert. | ||
1390 | 138 | (Issue #156, thanks jdreaver) | ||
1391 | 139 | - Fixed parsing of multiparemeter contexts. | ||
1392 | 140 | (Issue #174) | ||
1393 | 141 | |||
1394 | 142 | |||
1395 | 143 | 0.5.1 (2014-06-03) | ||
1396 | 144 | ------------------ | ||
1397 | 145 | |||
1398 | 146 | - Implemented a standard way to change the registry used in unpickling operations. | ||
1399 | 147 | (Issue #148) | ||
1400 | 148 | - Fix bug where conversion would fail due to caching. | ||
1401 | 149 | (Issue #140, thanks jdreaver) | ||
1402 | 150 | - Allow assigning Not a Number to a quantity array. | ||
1403 | 151 | (Issue #127) | ||
1404 | 152 | - Decoupled Quantity in place and not in place unit conversion methods. | ||
1405 | 153 | - Return None in functions that modify quantities in place. | ||
1406 | 154 | - Improved testing infrastructure to check for unwanted warnings. | ||
1407 | 155 | - Added test function at the package level to run all tests. | ||
1408 | 156 | |||
1409 | 157 | |||
1410 | 158 | 0.5 (2014-05-07) | ||
1411 | 159 | ---------------- | ||
1412 | 160 | |||
1413 | 161 | - Improved test suite helper functions. | ||
1414 | 162 | - Print honors default format w/o format(). | ||
1415 | 163 | (Issue #132, thanks mankoff) | ||
1416 | 164 | - Fixed sum() by treating number zero as a special case. | ||
1417 | 165 | (Issue #122, thanks rec) | ||
1418 | 166 | - Improved behaviour in ScaleConverter, OffsetConverter and Quantity.to. | ||
1419 | 167 | (Issue #120) | ||
1420 | 168 | - Reimplemented loading of default definitions to allow Pint in a cx_freeze or similar package. | ||
1421 | 169 | (Issue #118, thanks jbmohler) | ||
1422 | 170 | - Implemented parsing of pretty printed units. | ||
1423 | 171 | (Issue #117, thanks jpgrayson) | ||
1424 | 172 | - Fixed representation of dimensionless quantities. | ||
1425 | 173 | (Issue #112, thanks rec) | ||
1426 | 174 | - Raise error when invalid formatting code is given. | ||
1427 | 175 | (Issue #111, thanks rec) | ||
1428 | 176 | - Default registry to lazy load, raise error on redefinition | ||
1429 | 177 | (Issue #108, thanks rec, aepsil0n) | ||
1430 | 178 | - Added condensed format. | ||
1431 | 179 | (Issue #107, thanks rec) | ||
1432 | 180 | - Added UnitRegistry () operator to parse expression replacing []. | ||
1433 | 181 | (Issue #106, thanks rec) | ||
1434 | 182 | - Optional case insensitive unit parsing. | ||
1435 | 183 | (Issue #105, thanks rec, jeremyfreeman, dbrnz) | ||
1436 | 184 | - Change the Quantity mutability depending on magnitude type. | ||
1437 | 185 | (Issue #104, thanks rec) | ||
1438 | 186 | - Implemented API to list compatible units. | ||
1439 | 187 | (Issue #89) | ||
1440 | 188 | - Implemented cache of key UnitRegistry methods. | ||
1441 | 189 | - Rewrote the Measurement class to use uncertainties. | ||
1442 | 190 | (Issue #24) | ||
1443 | 191 | |||
1444 | 192 | |||
1445 | 193 | 0.4.2 (2014-02-14) | ||
1446 | 194 | ------------------ | ||
1447 | 195 | |||
1448 | 196 | - Python 2.6 support | ||
1449 | 197 | (Issue #96, thanks tiagocoutinho) | ||
1450 | 198 | - Fixed symbol for inch. | ||
1451 | 199 | (Issue #102, thanks cybertoast) | ||
1452 | 200 | - Stop raising AttributeError when wrapping funcs without all of the attributes. | ||
1453 | 201 | (Issue #100, thanks jturner314) | ||
1454 | 202 | - Fixed warning appearing in Py2.x when comparing a Numpy Array with an empty string. | ||
1455 | 203 | (Issue #98, thanks jturner314) | ||
1456 | 204 | - Add links to AUR packages in docs. | ||
1457 | 205 | (Issue #91, thanks jturner314) | ||
1458 | 206 | - Fixed garbage collection related problem. | ||
1459 | 207 | (Issue #92, thanks jturner314) | ||
1460 | 208 | |||
1461 | 209 | |||
1462 | 210 | 0.4.1 (2014-01-12) | ||
1463 | 211 | ------------------ | ||
1464 | 212 | |||
1465 | 213 | - Integer Division with Arrays. | ||
1466 | 214 | (Issue #80, thanks jdreaver) | ||
1467 | 215 | - Improved Documentation. | ||
1468 | 216 | (Issue #83, thanks choloepus) | ||
1469 | 217 | - Removed 'h' alias for hour due to conflict with Planck's constant. | ||
1470 | 218 | (Issue #82, thanks choloepus) | ||
1471 | 219 | - Improved get_base_units for non-multiplicative units. | ||
1472 | 220 | (Issue #85, thanks exxus) | ||
1473 | 221 | - Refactored code for multiplication. | ||
1474 | 222 | (Issue #84, thanks jturner314) | ||
1475 | 223 | - Removed 'R' alias for roentgen as it collides with molar_gas_constant. | ||
1476 | 224 | (Issue #87, thanks rsking84) | ||
1477 | 225 | - Improved naming of temperature units and multiplication of non-multiplicative units. | ||
1478 | 226 | (Issue #86, tahsnk exxus) | ||
1479 | 227 | |||
1480 | 228 | |||
1481 | 229 | |||
1482 | 230 | 0.4 (2013-12-17) | ||
1483 | 231 | ---------------- | ||
1484 | 232 | |||
1485 | 233 | - Introduced Contexts: relation between incompatible dimensions. | ||
1486 | 234 | (Issue #65) | ||
1487 | 235 | - Fixed get_base_units for non multiplicative units. | ||
1488 | 236 | (Related to issue #66) | ||
1489 | 237 | - Implemented default formatting for quantities. | ||
1490 | 238 | - Changed comparison between Quantities containing NumPy arrays. | ||
1491 | 239 | (Issue #75) - BACKWARDS INCOMPATIBLE CHANGE | ||
1492 | 240 | - Fixes for NumPy 1.8 due to changes in handling binary ops. | ||
1493 | 241 | (Issue #73) | ||
1494 | 242 | |||
1495 | 243 | |||
1496 | 244 | 0.3.3 (2013-11-29) | ||
1497 | 245 | ------------------ | ||
1498 | 246 | |||
1499 | 247 | - ParseHelper can now parse units named like python keywords. | ||
1500 | 248 | (Issue #69) | ||
1501 | 249 | - Fix comparison of quantities. | ||
1502 | 250 | (Issue #74) | ||
1503 | 251 | - Fix Inequality operator. | ||
1504 | 252 | (Issue #70, thanks muggenhor) | ||
1505 | 253 | - Improved travis configuration. | ||
1506 | 254 | (thanks muggenhor) | ||
1507 | 255 | |||
1508 | 256 | |||
1509 | 257 | 0.3.2 (2013-10-22) | ||
1510 | 258 | ------------------ | ||
1511 | 259 | |||
1512 | 260 | - Fix get_dimensionality for non multiplicative units. | ||
1513 | 261 | (Issue #66) | ||
1514 | 262 | - Proper handling of @import directive inside a file read using pkg_resources. | ||
1515 | 263 | (Issue #68) | ||
1516 | 264 | |||
1517 | 265 | |||
1518 | 266 | 0.3.1 (2013-09-15) | ||
1519 | 267 | ------------------ | ||
1520 | 268 | |||
1521 | 269 | - fix right division on python 2.7 | ||
1522 | 270 | (Issue #58, thanks natezb) | ||
1523 | 271 | - fix formatting of fractional exponentials between 0 and 1. | ||
1524 | 272 | (Issue #62, thanks jdreaver) | ||
1525 | 273 | - fix installation as egg. | ||
1526 | 274 | (Issue #61) | ||
1527 | 275 | - fix handling of strange values as input of Quantity. | ||
1528 | 276 | (Issue #53) | ||
1529 | 277 | - math operations between quantities of different registries now raise a ValueError. | ||
1530 | 278 | (Issue #52) | ||
1531 | 279 | |||
1532 | 280 | |||
1533 | 281 | 0.3 (2013-09-02) | ||
1534 | 282 | ---------------- | ||
1535 | 283 | |||
1536 | 284 | - support for IPython autocomplete and rich display. | ||
1537 | 285 | (Issues #30 and #31) | ||
1538 | 286 | - support for @import directive in definitions file. | ||
1539 | 287 | (Issue #22) | ||
1540 | 288 | - support for wrapping functions to make them pint-aware. | ||
1541 | 289 | (Issue #16) | ||
1542 | 290 | - support for comparing UnitsContainer to string. | ||
1543 | 291 | (Issue #35) | ||
1544 | 292 | - fix error raised while converting from a single unit to one expressed as | ||
1545 | 293 | the relation between many. | ||
1546 | 294 | (Issue #29) | ||
1547 | 295 | - fix error raised when unit symbol is missing. | ||
1548 | 296 | (Issue #41) | ||
1549 | 297 | - fix error raised when magnitude is Decimal. | ||
1550 | 298 | (Issue #46, thanks danielsokolowski) | ||
1551 | 299 | - support for non-installed pint. | ||
1552 | 300 | (Issue #42, thanks danielsokolowski) | ||
1553 | 301 | - support for application of numpy function on non-ndarray magnitudes. | ||
1554 | 302 | (Issue #44) | ||
1555 | 303 | - support for math operations on dimensionless Quantities (written with units). | ||
1556 | 304 | (Issue #45) | ||
1557 | 305 | - fix obtaining dimensionless quantity from string. | ||
1558 | 306 | (Issue #50) | ||
1559 | 307 | - fix adding and comparing numbers to a dimensionless quantity (written with units). | ||
1560 | 308 | (Issue #54) | ||
1561 | 309 | - Support for iter in Quantity. | ||
1562 | 310 | (Issue #55, thanks natezb) | ||
1563 | 311 | |||
1564 | 312 | |||
1565 | 313 | 0.2.1 (2013-07-02) | ||
1566 | 314 | ------------------ | ||
1567 | 315 | |||
1568 | 316 | - fix error raised while converting from a single unit to one expressed as | ||
1569 | 317 | the relation between many. | ||
1570 | 318 | (Issue #29) | ||
1571 | 319 | |||
1572 | 320 | |||
1573 | 321 | 0.2 (2013-05-13) | ||
1574 | 322 | ---------------- | ||
1575 | 323 | |||
1576 | 324 | - support for Measurement (Quantity +/- error). | ||
1577 | 325 | - implemented buckingham pi theorem for dimensional analysis. | ||
1578 | 326 | - support for temperature units and temperature difference units. | ||
1579 | 327 | - parser can infers if the user mean temperature or temperature difference. | ||
1580 | 328 | - support for derived dimensions (e.g. [speed] = [length] / [time]). | ||
1581 | 329 | - refactored the code into multiple files. | ||
1582 | 330 | - refactored code to isolate definitions and converters. | ||
1583 | 331 | - refactored formatter out of UnitParser class. | ||
1584 | 332 | - added tox and travis config files for CI. | ||
1585 | 333 | - comprehensive NumPy testing including almost all ufuncs. | ||
1586 | 334 | - full NumPy support (features is not longer experimental). | ||
1587 | 335 | - fixed bug preventing from having independent registries. | ||
1588 | 336 | (Issue #10, thanks bwanders) | ||
1589 | 337 | - forces real division as default for Quantities. | ||
1590 | 338 | (Issue #7, thanks dbrnz) | ||
1591 | 339 | - improved default unit definition file. | ||
1592 | 340 | (Issue #13, thanks r-barnes) | ||
1593 | 341 | - smarter parser supporting spaces as multiplications and other nice features. | ||
1594 | 342 | (Issue #13, thanks r-barnes) | ||
1595 | 343 | - moved testsuite inside package. | ||
1596 | 344 | - short forms of binary prefixes, more units and fix to less than comparison. | ||
1597 | 345 | (Issue #20, thanks muggenhor) | ||
1598 | 346 | - pint is now zip-safe | ||
1599 | 347 | (Issue #23, thanks muggenhor) | ||
1600 | 348 | |||
1601 | 349 | |||
1602 | 350 | Version 0.1.3 (2013-01-07) | ||
1603 | 351 | -------------------------- | ||
1604 | 352 | |||
1605 | 353 | - abbreviated quantity string formating. | ||
1606 | 354 | - complete Python 2.7 compatibility. | ||
1607 | 355 | - implemented pickle support for Quantities objects. | ||
1608 | 356 | - extended NumPy support. | ||
1609 | 357 | - various bugfixes. | ||
1610 | 358 | |||
1611 | 359 | |||
1612 | 360 | Version 0.1.2 (2012-08-12) | ||
1613 | 361 | -------------------------- | ||
1614 | 362 | |||
1615 | 363 | - experimenal NumPy support. | ||
1616 | 364 | - included default unit definitions file. | ||
1617 | 365 | (Issue #1, thanks fish2000) | ||
1618 | 366 | - better testing. | ||
1619 | 367 | - various bugfixes. | ||
1620 | 368 | - fixed some units definitions. | ||
1621 | 369 | (Issue #4, thanks craigholm) | ||
1622 | 370 | |||
1623 | 371 | |||
1624 | 372 | Version 0.1.1 (2012-07-31) | ||
1625 | 373 | -------------------------- | ||
1626 | 374 | |||
1627 | 375 | - better packaging and installation. | ||
1628 | 376 | |||
1629 | 377 | |||
1630 | 378 | Version 0.1 (2012-07-26) | ||
1631 | 379 | -------------------------- | ||
1632 | 380 | |||
1633 | 381 | - first public release. | ||
1634 | 382 | |||
1635 | 383 | Keywords: physical quantities unit conversion science | ||
1636 | 384 | Platform: UNKNOWN | ||
1637 | 385 | Classifier: Development Status :: 4 - Beta | ||
1638 | 386 | Classifier: Intended Audience :: Developers | ||
1639 | 387 | Classifier: Intended Audience :: Science/Research | ||
1640 | 388 | Classifier: License :: OSI Approved :: BSD License | ||
1641 | 389 | Classifier: Operating System :: MacOS :: MacOS X | ||
1642 | 390 | Classifier: Operating System :: Microsoft :: Windows | ||
1643 | 391 | Classifier: Operating System :: POSIX | ||
1644 | 392 | Classifier: Programming Language :: Python | ||
1645 | 393 | Classifier: Topic :: Scientific/Engineering | ||
1646 | 394 | Classifier: Topic :: Software Development :: Libraries | ||
1647 | 395 | Classifier: Programming Language :: Python :: 2.6 | ||
1648 | 396 | Classifier: Programming Language :: Python :: 2.7 | ||
1649 | 397 | Classifier: Programming Language :: Python :: 3.0 | ||
1650 | 398 | Classifier: Programming Language :: Python :: 3.1 | ||
1651 | 399 | Classifier: Programming Language :: Python :: 3.2 | ||
1652 | 400 | Classifier: Programming Language :: Python :: 3.3 | ||
1653 | 0 | 401 | ||
1654 | === added file 'Pint.egg-info/SOURCES.txt' | |||
1655 | --- Pint.egg-info/SOURCES.txt 1970-01-01 00:00:00 +0000 | |||
1656 | +++ Pint.egg-info/SOURCES.txt 2015-01-07 15:51:38 +0000 | |||
1657 | @@ -0,0 +1,72 @@ | |||
1658 | 1 | AUTHORS | ||
1659 | 2 | CHANGES | ||
1660 | 3 | CHANGES_DEV | ||
1661 | 4 | LICENSE | ||
1662 | 5 | MANIFEST.in | ||
1663 | 6 | README | ||
1664 | 7 | setup.cfg | ||
1665 | 8 | setup.py | ||
1666 | 9 | Pint.egg-info/PKG-INFO | ||
1667 | 10 | Pint.egg-info/SOURCES.txt | ||
1668 | 11 | Pint.egg-info/dependency_links.txt | ||
1669 | 12 | Pint.egg-info/entry_points.txt | ||
1670 | 13 | Pint.egg-info/top_level.txt | ||
1671 | 14 | Pint.egg-info/zip-safe | ||
1672 | 15 | bench/bench.py | ||
1673 | 16 | bench/bench_base.yaml | ||
1674 | 17 | bench/bench_numpy.yaml | ||
1675 | 18 | docs/Makefile | ||
1676 | 19 | docs/conf.py | ||
1677 | 20 | docs/contexts.rst | ||
1678 | 21 | docs/contributing.rst | ||
1679 | 22 | docs/defining.rst | ||
1680 | 23 | docs/faq.rst | ||
1681 | 24 | docs/getting.rst | ||
1682 | 25 | docs/index.rst | ||
1683 | 26 | docs/make.bat | ||
1684 | 27 | docs/measurement.rst | ||
1685 | 28 | docs/nonmult.rst | ||
1686 | 29 | docs/numpy.rst | ||
1687 | 30 | docs/pitheorem.rst | ||
1688 | 31 | docs/serialization.rst | ||
1689 | 32 | docs/tutorial.rst | ||
1690 | 33 | docs/wrapping.rst | ||
1691 | 34 | docs/_static/logo-full.jpg | ||
1692 | 35 | docs/_templates/sidebarintro.html | ||
1693 | 36 | docs/_templates/sidebarlogo.html | ||
1694 | 37 | docs/_themes/.gitignore | ||
1695 | 38 | docs/_themes/LICENSE | ||
1696 | 39 | docs/_themes/README | ||
1697 | 40 | docs/_themes/flask_theme_support.py | ||
1698 | 41 | docs/_themes/flask/layout.html | ||
1699 | 42 | docs/_themes/flask/relations.html | ||
1700 | 43 | docs/_themes/flask/theme.conf | ||
1701 | 44 | docs/_themes/flask/static/flasky.css_t | ||
1702 | 45 | docs/_themes/flask/static/small_flask.css | ||
1703 | 46 | pint/__init__.py | ||
1704 | 47 | pint/constants_en.txt | ||
1705 | 48 | pint/context.py | ||
1706 | 49 | pint/default_en.txt | ||
1707 | 50 | pint/formatting.py | ||
1708 | 51 | pint/measurement.py | ||
1709 | 52 | pint/quantity.py | ||
1710 | 53 | pint/unit.py | ||
1711 | 54 | pint/util.py | ||
1712 | 55 | pint/compat/__init__.py | ||
1713 | 56 | pint/compat/chainmap.py | ||
1714 | 57 | pint/compat/lrucache.py | ||
1715 | 58 | pint/compat/nullhandler.py | ||
1716 | 59 | pint/compat/transformdict.py | ||
1717 | 60 | pint/testsuite/__init__.py | ||
1718 | 61 | pint/testsuite/helpers.py | ||
1719 | 62 | pint/testsuite/parameterized.py | ||
1720 | 63 | pint/testsuite/test_contexts.py | ||
1721 | 64 | pint/testsuite/test_formatter.py | ||
1722 | 65 | pint/testsuite/test_issues.py | ||
1723 | 66 | pint/testsuite/test_measurement.py | ||
1724 | 67 | pint/testsuite/test_numpy.py | ||
1725 | 68 | pint/testsuite/test_pitheorem.py | ||
1726 | 69 | pint/testsuite/test_quantity.py | ||
1727 | 70 | pint/testsuite/test_umath.py | ||
1728 | 71 | pint/testsuite/test_unit.py | ||
1729 | 72 | pint/testsuite/test_util.py | ||
1730 | 0 | \ No newline at end of file | 73 | \ No newline at end of file |
1731 | 1 | 74 | ||
1732 | === added file 'Pint.egg-info/dependency_links.txt' | |||
1733 | --- Pint.egg-info/dependency_links.txt 1970-01-01 00:00:00 +0000 | |||
1734 | +++ Pint.egg-info/dependency_links.txt 2015-01-07 15:51:38 +0000 | |||
1735 | @@ -0,0 +1,1 @@ | |||
1736 | 1 | |||
1737 | 0 | 2 | ||
1738 | === added file 'Pint.egg-info/entry_points.txt' | |||
1739 | --- Pint.egg-info/entry_points.txt 1970-01-01 00:00:00 +0000 | |||
1740 | +++ Pint.egg-info/entry_points.txt 2015-01-07 15:51:38 +0000 | |||
1741 | @@ -0,0 +1,3 @@ | |||
1742 | 1 | [zest.releaser.releaser.after_checkout] | ||
1743 | 2 | pyroma = pint:_run_pyroma | ||
1744 | 3 | |||
1745 | 0 | 4 | ||
1746 | === added file 'Pint.egg-info/top_level.txt' | |||
1747 | --- Pint.egg-info/top_level.txt 1970-01-01 00:00:00 +0000 | |||
1748 | +++ Pint.egg-info/top_level.txt 2015-01-07 15:51:38 +0000 | |||
1749 | @@ -0,0 +1,1 @@ | |||
1750 | 1 | pint | ||
1751 | 0 | 2 | ||
1752 | === added file 'Pint.egg-info/zip-safe' | |||
1753 | --- Pint.egg-info/zip-safe 1970-01-01 00:00:00 +0000 | |||
1754 | +++ Pint.egg-info/zip-safe 2015-01-07 15:51:38 +0000 | |||
1755 | @@ -0,0 +1,1 @@ | |||
1756 | 1 | |||
1757 | 0 | 2 | ||
1758 | === modified file 'debian/changelog' | |||
1759 | --- debian/changelog 2014-09-05 23:26:05 +0000 | |||
1760 | +++ debian/changelog 2015-01-07 15:51:38 +0000 | |||
1761 | @@ -1,3 +1,10 @@ | |||
1762 | 1 | python-pint (0.6-0ubuntu1) UNRELEASED; urgency=medium | ||
1763 | 2 | |||
1764 | 3 | * New upstream release. | ||
1765 | 4 | * d/control: Add python-numpy and python3-numpy to Build-Depends. | ||
1766 | 5 | |||
1767 | 6 | -- Corey Bryant <corey.bryant@canonical.com> Wed, 07 Jan 2015 10:47:04 -0500 | ||
1768 | 7 | |||
1769 | 1 | python-pint (0.5.2-1) unstable; urgency=medium | 8 | python-pint (0.5.2-1) unstable; urgency=medium |
1770 | 2 | 9 | ||
1771 | 3 | * Initial release. (Closes: #760586) | 10 | * Initial release. (Closes: #760586) |
1772 | 4 | 11 | ||
1773 | === modified file 'debian/control' | |||
1774 | --- debian/control 2014-09-05 23:26:05 +0000 | |||
1775 | +++ debian/control 2015-01-07 15:51:38 +0000 | |||
1776 | @@ -6,11 +6,13 @@ | |||
1777 | 6 | Build-Depends: debhelper (>= 9), | 6 | Build-Depends: debhelper (>= 9), |
1778 | 7 | python-all (>= 2.6.6-3~), | 7 | python-all (>= 2.6.6-3~), |
1779 | 8 | python-nose, | 8 | python-nose, |
1780 | 9 | python-numpy, | ||
1781 | 9 | python-setuptools, | 10 | python-setuptools, |
1782 | 10 | python-sphinx, | 11 | python-sphinx, |
1783 | 11 | python-yaml, | 12 | python-yaml, |
1784 | 12 | python3-all, | 13 | python3-all, |
1785 | 13 | python3-nose, | 14 | python3-nose, |
1786 | 15 | python3-numpy, | ||
1787 | 14 | python3-setuptools, | 16 | python3-setuptools, |
1788 | 15 | python3-yaml | 17 | python3-yaml |
1789 | 16 | Standards-Version: 3.9.5 | 18 | Standards-Version: 3.9.5 |
1790 | 17 | 19 | ||
1791 | === modified file 'debian/watch' | |||
1792 | --- debian/watch 2014-09-05 23:26:05 +0000 | |||
1793 | +++ debian/watch 2015-01-07 15:51:38 +0000 | |||
1794 | @@ -1,3 +1,3 @@ | |||
1795 | 1 | version=3 | 1 | version=3 |
1798 | 2 | http://pypi.python.org/packages/source/P/Pint Pint-(.*).tar.gz | 2 | opts="uversionmangle=s/.zip//" \ |
1799 | 3 | 3 | http://pypi.python.org/packages/source/P/Pint/ Pint-(.*).zip | |
1800 | 4 | 4 | ||
1801 | === modified file 'docs/_themes/flask/layout.html' | |||
1802 | --- docs/_themes/flask/layout.html 2014-09-05 23:26:05 +0000 | |||
1803 | +++ docs/_themes/flask/layout.html 2015-01-07 15:51:38 +0000 | |||
1804 | @@ -10,7 +10,7 @@ | |||
1805 | 10 | {%- block relbar2 %} | 10 | {%- block relbar2 %} |
1806 | 11 | {% if theme_github_fork %} | 11 | {% if theme_github_fork %} |
1807 | 12 | <a href="http://github.com/{{ theme_github_fork }}"><img style="position: fixed; top: 0; right: 0; border: 0;" | 12 | <a href="http://github.com/{{ theme_github_fork }}"><img style="position: fixed; top: 0; right: 0; border: 0;" |
1809 | 13 | src="" alt="Fork me on GitHub" /></a> | 13 | src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub" /></a> |
1810 | 14 | {% endif %} | 14 | {% endif %} |
1811 | 15 | {% endblock %} | 15 | {% endblock %} |
1812 | 16 | {% block header %} | 16 | {% block header %} |
1813 | 17 | 17 | ||
1814 | === modified file 'docs/conf.py' | |||
1815 | --- docs/conf.py 2014-09-05 23:26:05 +0000 | |||
1816 | +++ docs/conf.py 2015-01-07 15:51:38 +0000 | |||
1817 | @@ -28,7 +28,7 @@ | |||
1818 | 28 | 28 | ||
1819 | 29 | # Add any Sphinx extension module names here, as strings. They can be extensions | 29 | # Add any Sphinx extension module names here, as strings. They can be extensions |
1820 | 30 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. | 30 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. |
1822 | 31 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.coverage', 'sphinx.ext.viewcode'] | 31 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.coverage', 'sphinx.ext.viewcode', 'sphinx.ext.mathjax'] |
1823 | 32 | 32 | ||
1824 | 33 | # Add any paths that contain templates here, relative to this directory. | 33 | # Add any paths that contain templates here, relative to this directory. |
1825 | 34 | templates_path = ['_templates'] | 34 | templates_path = ['_templates'] |
1826 | 35 | 35 | ||
1827 | === modified file 'docs/contexts.rst' | |||
1828 | --- docs/contexts.rst 2014-09-05 23:26:05 +0000 | |||
1829 | +++ docs/contexts.rst 2015-01-07 15:51:38 +0000 | |||
1830 | @@ -108,6 +108,15 @@ | |||
1831 | 108 | >>> f.to('nm', 'sp', n=1.33) | 108 | >>> f.to('nm', 'sp', n=1.33) |
1832 | 109 | <Quantity(398.496240602, 'nanometer')> | 109 | <Quantity(398.496240602, 'nanometer')> |
1833 | 110 | 110 | ||
1834 | 111 | Contexts can also accept Pint Quantity objects as parameters. For example, the 'chemistry' | ||
1835 | 112 | context accepts the molecular weight of a substance (as a Quantity with dimensions of | ||
1836 | 113 | [mass]/[substance]) to allow conversion between moles and mass. | ||
1837 | 114 | |||
1838 | 115 | .. doctest:: | ||
1839 | 116 | |||
1840 | 117 | >>> substance = 95 * ureg('g') | ||
1841 | 118 | >>> moles = substance.to('moles', 'chemistry', mw = 5 * ureg('g/mol')) | ||
1842 | 119 | <Quantity(19.0, 'mole')> | ||
1843 | 111 | 120 | ||
1844 | 112 | 121 | ||
1845 | 113 | Defining contexts in a file | 122 | Defining contexts in a file |
1846 | @@ -129,7 +138,8 @@ | |||
1847 | 129 | All parameters are named and default values are mandatory. Multiple parameters | 138 | All parameters are named and default values are mandatory. Multiple parameters |
1848 | 130 | are separated by commas (like in a python function definition). Finally, you provide the name | 139 | are separated by commas (like in a python function definition). Finally, you provide the name |
1849 | 131 | of the context (e.g. spectroscopy) and, optionally, a short version of the name (e.g. sp) | 140 | of the context (e.g. spectroscopy) and, optionally, a short version of the name (e.g. sp) |
1851 | 132 | separated by an equal sign. | 141 | separated by an equal sign. See the definition of the 'chemistry' context in default_en.txt |
1852 | 142 | for an example of a multiple-parameter context. | ||
1853 | 133 | 143 | ||
1854 | 134 | Conversions rules are specified by providing source and destination dimensions separated | 144 | Conversions rules are specified by providing source and destination dimensions separated |
1855 | 135 | using a colon (`:`) from the equation. A special variable named `value` will be replaced | 145 | using a colon (`:`) from the equation. A special variable named `value` will be replaced |
1856 | @@ -140,6 +150,8 @@ | |||
1857 | 140 | from the first dimension to the second one. A double arrow (`<->`) is used to | 150 | from the first dimension to the second one. A double arrow (`<->`) is used to |
1858 | 141 | indicate that the transformation operates both ways. | 151 | indicate that the transformation operates both ways. |
1859 | 142 | 152 | ||
1860 | 153 | Context definitions are stored and imported exactly like custom units definition file | ||
1861 | 154 | (and can be included in the same file as unit definitions). See "Defining units" for details. | ||
1862 | 143 | 155 | ||
1863 | 144 | Defining contexts programmatically | 156 | Defining contexts programmatically |
1864 | 145 | ---------------------------------- | 157 | ---------------------------------- |
1865 | 146 | 158 | ||
1866 | === modified file 'docs/faq.rst' | |||
1867 | --- docs/faq.rst 2014-09-05 23:26:05 +0000 | |||
1868 | +++ docs/faq.rst 2015-01-07 15:51:38 +0000 | |||
1869 | @@ -13,6 +13,8 @@ | |||
1870 | 13 | You mention other similar Python libraries. Can you point me to those? | 13 | You mention other similar Python libraries. Can you point me to those? |
1871 | 14 | ---------------------------------------------------------------------- | 14 | ---------------------------------------------------------------------- |
1872 | 15 | 15 | ||
1873 | 16 | `natu <http://kdavies4.github.io/natu/>`_ | ||
1874 | 17 | |||
1875 | 16 | `Buckingham <https://code.google.com/p/buckingham/>`_ | 18 | `Buckingham <https://code.google.com/p/buckingham/>`_ |
1876 | 17 | 19 | ||
1877 | 18 | `Magnitude <http://github.com/juanre/magnitude.git>`_ | 20 | `Magnitude <http://github.com/juanre/magnitude.git>`_ |
1878 | 19 | 21 | ||
1879 | === modified file 'docs/index.rst' | |||
1880 | --- docs/index.rst 2014-09-05 23:26:05 +0000 | |||
1881 | +++ docs/index.rst 2015-01-07 15:51:38 +0000 | |||
1882 | @@ -9,7 +9,7 @@ | |||
1883 | 9 | 9 | ||
1884 | 10 | Pint is Python package to define, operate and manipulate **physical quantities**: the product of a numerical value and a unit of measurement. It allows arithmetic operations between them and conversions from and to different units. | 10 | Pint is Python package to define, operate and manipulate **physical quantities**: the product of a numerical value and a unit of measurement. It allows arithmetic operations between them and conversions from and to different units. |
1885 | 11 | 11 | ||
1887 | 12 | It is distributed with a comprehensive list of physical units, prefixes and constants. Due to its modular design, you can extend (or even rewrite!) the complete list without changing the source code. | 12 | It is distributed with a comprehensive list of physical units, prefixes and constants. Due to its modular design, you can extend (or even rewrite!) the complete list without changing the source code. It supports a lot of numpy mathematical operations without monkey patching or wrapping numpy. |
1888 | 13 | 13 | ||
1889 | 14 | It has a complete test coverage. It runs in Python 2.6+ and 3.2+ with no other dependency. It licensed under BSD. | 14 | It has a complete test coverage. It runs in Python 2.6+ and 3.2+ with no other dependency. It licensed under BSD. |
1890 | 15 | 15 | ||
1891 | 16 | 16 | ||
1892 | === modified file 'docs/nonmult.rst' | |||
1893 | --- docs/nonmult.rst 2014-09-05 23:26:05 +0000 | |||
1894 | +++ docs/nonmult.rst 2015-01-07 15:51:38 +0000 | |||
1895 | @@ -4,17 +4,17 @@ | |||
1896 | 4 | Temperature conversion | 4 | Temperature conversion |
1897 | 5 | ====================== | 5 | ====================== |
1898 | 6 | 6 | ||
1906 | 7 | Unlike meters and seconds, fahrenheits, celsius and kelvin are not | 7 | Unlike meters and seconds, the temperature units fahrenheits and |
1907 | 8 | multiplicative units. Temperature is expressed in a system with a | 8 | celsius are non-multiplicative units. These temperature units are |
1908 | 9 | reference point, and relations between temperature units include | 9 | expressed in a system with a reference point, and relations between |
1909 | 10 | not only an scaling factor but also an offset. Pint supports these | 10 | temperature units include not only a scaling factor but also an offset. |
1910 | 11 | type of units and conversions between them. The default definition | 11 | Pint supports these type of units and conversions between them. |
1911 | 12 | file includes fahrenheits, celsius, kelvin and rankine abbreviated | 12 | The default definition file includes fahrenheits, celsius, |
1912 | 13 | as degF, degC, degK, and degR. | 13 | kelvin and rankine abbreviated as degF, degC, degK, and degR. |
1913 | 14 | 14 | ||
1914 | 15 | For example, to convert from celsius to fahrenheit: | 15 | For example, to convert from celsius to fahrenheit: |
1915 | 16 | 16 | ||
1917 | 17 | .. testsetup:: * | 17 | .. testsetup:: |
1918 | 18 | 18 | ||
1919 | 19 | from pint import UnitRegistry | 19 | from pint import UnitRegistry |
1920 | 20 | ureg = UnitRegistry() | 20 | ureg = UnitRegistry() |
1921 | @@ -24,21 +24,23 @@ | |||
1922 | 24 | 24 | ||
1923 | 25 | >>> from pint import UnitRegistry | 25 | >>> from pint import UnitRegistry |
1924 | 26 | >>> ureg = UnitRegistry() | 26 | >>> ureg = UnitRegistry() |
1926 | 27 | >>> home = 25.4 * ureg.degC | 27 | >>> Q_ = ureg.Quantity |
1927 | 28 | >>> home = Q_(25.4, ureg.degC) | ||
1928 | 28 | >>> print(home.to('degF')) | 29 | >>> print(home.to('degF')) |
1930 | 29 | 77.72000039999993 degF | 30 | 77.7200004 degF |
1931 | 30 | 31 | ||
1932 | 31 | or to other kelvin or rankine: | 32 | or to other kelvin or rankine: |
1933 | 32 | 33 | ||
1934 | 33 | .. doctest:: | 34 | .. doctest:: |
1935 | 34 | 35 | ||
1938 | 35 | >>> print(home.to('degK')) | 36 | >>> print(home.to('kelvin')) |
1939 | 36 | 298.54999999999995 degK | 37 | 298.55 kelvin |
1940 | 37 | >>> print(home.to('degR')) | 38 | >>> print(home.to('degR')) |
1941 | 38 | 537.39 degR | 39 | 537.39 degR |
1942 | 39 | 40 | ||
1945 | 40 | Additionally, for every temperature unit in the registry, | 41 | Additionally, for every non-multiplicative temperature unit |
1946 | 41 | there is also a *delta* counterpart to specify differences. | 42 | in the registry, there is also a *delta* counterpart to specify |
1947 | 43 | differences. Absolute units have no *delta* counterpart. | ||
1948 | 42 | For example, the change in celsius is equal to the change | 44 | For example, the change in celsius is equal to the change |
1949 | 43 | in kelvin, but not in fahrenheit (as the scaling factor | 45 | in kelvin, but not in fahrenheit (as the scaling factor |
1950 | 44 | is different). | 46 | is different). |
1951 | @@ -46,20 +48,61 @@ | |||
1952 | 46 | .. doctest:: | 48 | .. doctest:: |
1953 | 47 | 49 | ||
1954 | 48 | >>> increase = 12.3 * ureg.delta_degC | 50 | >>> increase = 12.3 * ureg.delta_degC |
1957 | 49 | >>> print(increase.to(ureg.delta_degK)) | 51 | >>> print(increase.to(ureg.kelvin)) |
1958 | 50 | 12.3 delta_degK | 52 | 12.3 kelvin |
1959 | 51 | >>> print(increase.to(ureg.delta_degF)) | 53 | >>> print(increase.to(ureg.delta_degF)) |
1961 | 52 | 6.833333333333334 delta_degF | 54 | 22.14 delta_degF |
1962 | 53 | 55 | ||
1963 | 54 | .. | 56 | .. |
1972 | 55 | Subtraction of two temperatures also yields a *delta* unit. | 57 | Subtraction of two temperatures given in offset units yields a *delta* unit: |
1973 | 56 | 58 | ||
1974 | 57 | .. doctest:: | 59 | .. doctest:: |
1975 | 58 | 60 | ||
1976 | 59 | >>> 25.4 * ureg.degC - 10. * ureg.degC | 61 | >>> Q_(25.4, ureg.degC) - Q_(10., ureg.degC) |
1977 | 60 | 15.4 delta_degC | 62 | <Quantity(15.4, 'delta_degC')> |
1978 | 61 | 63 | ||
1979 | 62 | Differences in temperature are multiplicative: | 64 | You can add or subtract a quantity with *delta* unit and a quantity with |
1980 | 65 | offset unit: | ||
1981 | 66 | |||
1982 | 67 | .. doctest:: | ||
1983 | 68 | |||
1984 | 69 | >>> Q_(25.4, ureg.degC) + Q_(10., ureg.delta_degC) | ||
1985 | 70 | <Quantity(35.4, 'degC')> | ||
1986 | 71 | >>> Q_(25.4, ureg.degC) - Q_(10., ureg.delta_degC) | ||
1987 | 72 | <Quantity(15.4, 'degC')> | ||
1988 | 73 | |||
1989 | 74 | If you want to add a quantity with absolute unit to one with offset unit, like here | ||
1990 | 75 | |||
1991 | 76 | .. doctest:: | ||
1992 | 77 | |||
1993 | 78 | >>> heating_rate = 0.5 * ureg.kelvin/ureg.min | ||
1994 | 79 | >>> Q_(10., ureg.degC) + heating_rate * Q_(30, ureg.min) | ||
1995 | 80 | Traceback (most recent call last): | ||
1996 | 81 | ... | ||
1997 | 82 | pint.unit.OffsetUnitCalculusError: Ambiguous operation with offset unit (degC, kelvin). | ||
1998 | 83 | |||
1999 | 84 | you have to avoid the ambiguity by either converting the offset unit to the | ||
2000 | 85 | absolute unit before addition | ||
2001 | 86 | |||
2002 | 87 | .. doctest:: | ||
2003 | 88 | |||
2004 | 89 | >>> Q_(10., ureg.degC).to(ureg.kelvin) + heating_rate * Q_(30, ureg.min) | ||
2005 | 90 | <Quantity(298.15, 'kelvin')> | ||
2006 | 91 | |||
2007 | 92 | or convert the absolute unit to a *delta* unit: | ||
2008 | 93 | |||
2009 | 94 | .. doctest:: | ||
2010 | 95 | |||
2011 | 96 | >>> Q_(10., ureg.degC) + heating_rate.to('delta_degC/min') * Q_(30, ureg.min) | ||
2012 | 97 | <Quantity(25.0, 'degC')> | ||
2013 | 98 | |||
2014 | 99 | In contrast to subtraction, the addition of quantities with offset units | ||
2015 | 100 | is ambiguous, e.g. for *10 degC + 100 degC* two different result are reasonable | ||
2016 | 101 | depending on the context, *110 degC* or *383.15 °C (= 283.15 K + 373.15 K)*. | ||
2017 | 102 | Because of this ambiguity pint raises an error for the addition of two | ||
2018 | 103 | quantities with offset units (since pint-0.6). | ||
2019 | 104 | |||
2020 | 105 | Quantities with *delta* units are multiplicative: | ||
2021 | 63 | 106 | ||
2022 | 64 | .. doctest:: | 107 | .. doctest:: |
2023 | 65 | 108 | ||
2024 | @@ -67,7 +110,55 @@ | |||
2025 | 67 | >>> print(speed.to('delta_degC/second')) | 110 | >>> print(speed.to('delta_degC/second')) |
2026 | 68 | 1.0 delta_degC / second | 111 | 1.0 delta_degC / second |
2027 | 69 | 112 | ||
2029 | 70 | The parser knows about *delta* units and use them when a temperature unit | 113 | However, multiplication, division and exponentiation of quantities with |
2030 | 114 | offset units is problematic just like addition. Pint (since version 0.6) | ||
2031 | 115 | will by default raise an error when a quantity with offset unit is used in | ||
2032 | 116 | these operations. Due to this quantities with offset units cannot be created | ||
2033 | 117 | like other quantities by multiplication of magnitude and unit but have | ||
2034 | 118 | to be explicitly created: | ||
2035 | 119 | |||
2036 | 120 | .. doctest:: | ||
2037 | 121 | |||
2038 | 122 | >>> home = 25.4 * ureg.degC | ||
2039 | 123 | Traceback (most recent call last): | ||
2040 | 124 | ... | ||
2041 | 125 | pint.unit.OffsetUnitCalculusError: Ambiguous operation with offset unit (degC). | ||
2042 | 126 | >>> Q_(25.4, ureg.degC) | ||
2043 | 127 | <Quantity(25.4, 'degC')> | ||
2044 | 128 | |||
2045 | 129 | As an alternative to raising an error, pint can be configured to work more | ||
2046 | 130 | relaxed via setting the UnitRegistry parameter *autoconvert_offset_to_baseunit* | ||
2047 | 131 | to true. In this mode, pint behaves differently: | ||
2048 | 132 | |||
2049 | 133 | * Multiplication of a quantity with a single offset unit with order +1 by | ||
2050 | 134 | a number or ndarray yields the quantity in the given unit. | ||
2051 | 135 | |||
2052 | 136 | .. doctest:: | ||
2053 | 137 | |||
2054 | 138 | >>> ureg = UnitRegistry(autoconvert_offset_to_baseunit = True) | ||
2055 | 139 | >>> T = 25.4 * ureg.degC | ||
2056 | 140 | >>> T | ||
2057 | 141 | <Quantity(25.4, 'degC')> | ||
2058 | 142 | |||
2059 | 143 | * Before all other multiplications, all divisions and in case of | ||
2060 | 144 | exponentiation [#f1]_ involving quantities with offset-units, pint | ||
2061 | 145 | will convert the quantities with offset units automatically to the | ||
2062 | 146 | corresponding base unit before performing the operation. | ||
2063 | 147 | |||
2064 | 148 | >>> 1/T | ||
2065 | 149 | <Quantity(0.00334952269302, '1 / kelvin')> | ||
2066 | 150 | >>> T * 10 * ureg.meter | ||
2067 | 151 | <Quantity(527.15, 'kelvin * meter')> | ||
2068 | 152 | |||
2069 | 153 | You can change the behaviour at any time: | ||
2070 | 154 | |||
2071 | 155 | >>> ureg.autoconvert_offset_to_baseunit = False | ||
2072 | 156 | >>> 1/T | ||
2073 | 157 | Traceback (most recent call last): | ||
2074 | 158 | ... | ||
2075 | 159 | pint.unit.OffsetUnitCalculusError: Ambiguous operation with offset unit (degC). | ||
2076 | 160 | |||
2077 | 161 | The parser knows about *delta* units and uses them when a temperature unit | ||
2078 | 71 | is found in a multiplicative context. For example, here: | 162 | is found in a multiplicative context. For example, here: |
2079 | 72 | 163 | ||
2080 | 73 | .. doctest:: | 164 | .. doctest:: |
2081 | @@ -86,9 +177,15 @@ | |||
2082 | 86 | 177 | ||
2083 | 87 | .. doctest:: | 178 | .. doctest:: |
2084 | 88 | 179 | ||
2086 | 89 | >>> print(ureg.parse_units('degC/meter', to_delta=False)) | 180 | >>> print(ureg.parse_units('degC/meter', as_delta=False)) |
2087 | 90 | degC / meter | 181 | degC / meter |
2088 | 91 | 182 | ||
2089 | 183 | Note that the magnitude is left unchanged: | ||
2090 | 184 | |||
2091 | 185 | .. doctest:: | ||
2092 | 186 | |||
2093 | 187 | >>> Q_(10, 'degC/meter') | ||
2094 | 188 | <Quantity(10, 'delta_degC / meter')> | ||
2095 | 92 | 189 | ||
2096 | 93 | To define a new temperature, you need to specify the offset. For example, | 190 | To define a new temperature, you need to specify the offset. For example, |
2097 | 94 | this is the definition of the celsius and fahrenheit:: | 191 | this is the definition of the celsius and fahrenheit:: |
2098 | @@ -98,3 +195,5 @@ | |||
2099 | 98 | 195 | ||
2100 | 99 | You do not need to define *delta* units, as they are defined automatically. | 196 | You do not need to define *delta* units, as they are defined automatically. |
2101 | 100 | 197 | ||
2102 | 198 | .. [#f1] If the exponent is +1, the quantity will not be converted to base | ||
2103 | 199 | unit but remains unchanged. | ||
2104 | 101 | \ No newline at end of file | 200 | \ No newline at end of file |
2105 | 102 | 201 | ||
2106 | === modified file 'docs/serialization.rst' | |||
2107 | --- docs/serialization.rst 2014-09-05 23:26:05 +0000 | |||
2108 | +++ docs/serialization.rst 2015-01-07 15:51:38 +0000 | |||
2109 | @@ -19,7 +19,7 @@ | |||
2110 | 19 | >>> import pint | 19 | >>> import pint |
2111 | 20 | >>> ureg = pint.UnitRegistry() | 20 | >>> ureg = pint.UnitRegistry() |
2112 | 21 | >>> duration = 24.2 * ureg.years | 21 | >>> duration = 24.2 * ureg.years |
2114 | 22 | >>> print(duration) | 22 | >>> duration |
2115 | 23 | <Quantity(24.2, 'year')> | 23 | <Quantity(24.2, 'year')> |
2116 | 24 | >>> serialized = str(duration) | 24 | >>> serialized = str(duration) |
2117 | 25 | >>> print(serialized) | 25 | >>> print(serialized) |
2118 | @@ -37,7 +37,7 @@ | |||
2119 | 37 | >>> ureg = pint.UnitRegistry() | 37 | >>> ureg = pint.UnitRegistry() |
2120 | 38 | >>> duration = ureg('24.2 year') | 38 | >>> duration = ureg('24.2 year') |
2121 | 39 | >>> print(duration) | 39 | >>> print(duration) |
2123 | 40 | <Quantity(24.2, 'year')> | 40 | 24.2 year |
2124 | 41 | 41 | ||
2125 | 42 | Notice that the serialized quantity is likely to be parsed in **another** registry | 42 | Notice that the serialized quantity is likely to be parsed in **another** registry |
2126 | 43 | as shown in this example. Pint Quantities do not exist on their own but they are | 43 | as shown in this example. Pint Quantities do not exist on their own but they are |
2127 | @@ -72,6 +72,7 @@ | |||
2128 | 72 | 72 | ||
2129 | 73 | >>> magnitude, units = pickle.loads(serialized) | 73 | >>> magnitude, units = pickle.loads(serialized) |
2130 | 74 | >>> ureg.Quantity(magnitude, units) | 74 | >>> ureg.Quantity(magnitude, units) |
2131 | 75 | <Quantity(24.2, 'year')> | ||
2132 | 75 | 76 | ||
2133 | 76 | You can use the same mechanism with any serialization protocol, not only with binary ones. | 77 | You can use the same mechanism with any serialization protocol, not only with binary ones. |
2134 | 77 | (In fact, version 0 of the Pickle protocol is ascii). Other common serialization protocols/packages | 78 | (In fact, version 0 of the Pickle protocol is ascii). Other common serialization protocols/packages |
2135 | 78 | 79 | ||
2136 | === modified file 'docs/tutorial.rst' | |||
2137 | --- docs/tutorial.rst 2014-09-05 23:26:05 +0000 | |||
2138 | +++ docs/tutorial.rst 2015-01-07 15:51:38 +0000 | |||
2139 | @@ -96,7 +96,6 @@ | |||
2140 | 96 | >>> print(height) | 96 | >>> print(height) |
2141 | 97 | 5.75 foot | 97 | 5.75 foot |
2142 | 98 | >>> height.ito_base_units() | 98 | >>> height.ito_base_units() |
2143 | 99 | <Quantity(1.7526, 'meter')> | ||
2144 | 100 | >>> print(height) | 99 | >>> print(height) |
2145 | 101 | 1.7526 meter | 100 | 1.7526 meter |
2146 | 102 | 101 | ||
2147 | 103 | 102 | ||
2148 | === modified file 'pint/__init__.py' | |||
2149 | --- pint/__init__.py 2014-09-05 23:26:05 +0000 | |||
2150 | +++ pint/__init__.py 2015-01-07 15:51:38 +0000 | |||
2151 | @@ -16,25 +16,19 @@ | |||
2152 | 16 | import subprocess | 16 | import subprocess |
2153 | 17 | import pkg_resources | 17 | import pkg_resources |
2154 | 18 | from .formatting import formatter | 18 | from .formatting import formatter |
2156 | 19 | from .unit import UnitRegistry, DimensionalityError, UndefinedUnitError, LazyRegistry | 19 | from .unit import (UnitRegistry, DimensionalityError, OffsetUnitCalculusError, |
2157 | 20 | UndefinedUnitError, LazyRegistry) | ||
2158 | 20 | from .util import pi_theorem, logger | 21 | from .util import pi_theorem, logger |
2159 | 21 | 22 | ||
2160 | 22 | from .context import Context | 23 | from .context import Context |
2161 | 23 | 24 | ||
2162 | 24 | 25 | ||
2176 | 25 | __version__ = "unknown" | 26 | try: # pragma: no cover |
2177 | 26 | try: # pragma: no cover | 27 | __version__ = pkg_resources.get_distribution('pint').version |
2178 | 27 | # try to grab the commit version of our package | 28 | except: # pragma: no cover |
2179 | 28 | __version__ = (subprocess.check_output(["git", "describe"], | 29 | # we seem to have a local copy not installed without setuptools |
2180 | 29 | stderr=subprocess.STDOUT, | 30 | # so the reported version will be unknown |
2181 | 30 | cwd=os.path.dirname(os.path.abspath(__file__)))).strip() | 31 | __version__ = "unknown" |
2169 | 31 | except: # pragma: no cover | ||
2170 | 32 | # on any error just try to grab the version that is installed on the system | ||
2171 | 33 | try: | ||
2172 | 34 | __version__ = pkg_resources.get_distribution('pint').version | ||
2173 | 35 | except: # pragma: no cover | ||
2174 | 36 | pass # we seem to have a local copy without any repository control or installed without setuptools | ||
2175 | 37 | # so the reported version will be __unknown__ | ||
2182 | 38 | 32 | ||
2183 | 39 | 33 | ||
2184 | 40 | #: A Registry with the default units and constants. | 34 | #: A Registry with the default units and constants. |
2185 | @@ -81,6 +75,47 @@ | |||
2186 | 81 | sys.exit(1) | 75 | sys.exit(1) |
2187 | 82 | 76 | ||
2188 | 83 | 77 | ||
2189 | 78 | def _check_travis(data): # pragma: no cover | ||
2190 | 79 | """Check if Travis reports that everything is ok. | ||
2191 | 80 | (used to perform checks before releasing a new version). | ||
2192 | 81 | """ | ||
2193 | 82 | import json | ||
2194 | 83 | import sys | ||
2195 | 84 | |||
2196 | 85 | from zest.releaser.utils import system, ask | ||
2197 | 86 | if not ask('Check with Travis before releasing?'): | ||
2198 | 87 | return | ||
2199 | 88 | |||
2200 | 89 | try: | ||
2201 | 90 | # Python 3 | ||
2202 | 91 | from urllib.request import urlopen | ||
2203 | 92 | def get(url): | ||
2204 | 93 | return urlopen(url).read().decode('utf-8') | ||
2205 | 94 | |||
2206 | 95 | except ImportError: | ||
2207 | 96 | # Python 2 | ||
2208 | 97 | from urllib2 import urlopen | ||
2209 | 98 | def get(url): | ||
2210 | 99 | return urlopen(url).read() | ||
2211 | 100 | |||
2212 | 101 | url = 'https://api.github.com/repos/%s/%s/status/%s' | ||
2213 | 102 | |||
2214 | 103 | username = 'hgrecco' | ||
2215 | 104 | repo = 'pint' | ||
2216 | 105 | commit = system('git rev-parse HEAD') | ||
2217 | 106 | |||
2218 | 107 | try: | ||
2219 | 108 | result = json.loads(get(url % (username, repo, commit)))['state'] | ||
2220 | 109 | print('Travis says: %s' % result) | ||
2221 | 110 | if result != 'success': | ||
2222 | 111 | if not ask('Do you want to continue anyway?', default=False): | ||
2223 | 112 | sys.exit(1) | ||
2224 | 113 | except Exception: | ||
2225 | 114 | print('Could not determine the commit state with Travis.') | ||
2226 | 115 | if ask('Do you want to continue anyway?', default=False): | ||
2227 | 116 | sys.exit(1) | ||
2228 | 117 | |||
2229 | 118 | |||
2230 | 84 | def test(): | 119 | def test(): |
2231 | 85 | """Run all tests. | 120 | """Run all tests. |
2232 | 86 | 121 | ||
2233 | 87 | 122 | ||
2234 | === modified file 'pint/default_en.txt' | |||
2235 | --- pint/default_en.txt 2014-09-05 23:26:05 +0000 | |||
2236 | +++ pint/default_en.txt 2015-01-07 15:51:38 +0000 | |||
2237 | @@ -10,7 +10,7 @@ | |||
2238 | 10 | femto- = 1e-15 = f- | 10 | femto- = 1e-15 = f- |
2239 | 11 | pico- = 1e-12 = p- | 11 | pico- = 1e-12 = p- |
2240 | 12 | nano- = 1e-9 = n- | 12 | nano- = 1e-9 = n- |
2242 | 13 | micro- = 1e-6 = u- | 13 | micro- = 1e-6 = u- = µ- |
2243 | 14 | milli- = 1e-3 = m- | 14 | milli- = 1e-3 = m- |
2244 | 15 | centi- = 1e-2 = c- | 15 | centi- = 1e-2 = c- |
2245 | 16 | deci- = 1e-1 = d- | 16 | deci- = 1e-1 = d- |
2246 | @@ -76,7 +76,7 @@ | |||
2247 | 76 | coulomb = ampere * second = C | 76 | coulomb = ampere * second = C |
2248 | 77 | volt = joule / coulomb = V | 77 | volt = joule / coulomb = V |
2249 | 78 | farad = coulomb / volt = F | 78 | farad = coulomb / volt = F |
2251 | 79 | ohm = volt / ampere | 79 | ohm = volt / ampere = Ω |
2252 | 80 | siemens = ampere / volt = S = mho | 80 | siemens = ampere / volt = S = mho |
2253 | 81 | weber = volt * second = Wb | 81 | weber = volt * second = Wb |
2254 | 82 | tesla = weber / meter ** 2 = T | 82 | tesla = weber / meter ** 2 = T |
2255 | @@ -138,7 +138,7 @@ | |||
2256 | 138 | baud = bit / second = Bd = bps | 138 | baud = bit / second = Bd = bps |
2257 | 139 | 139 | ||
2258 | 140 | # Length | 140 | # Length |
2260 | 141 | angstrom = 1e-10 * meter | 141 | angstrom = 1e-10 * meter = ångström = Å |
2261 | 142 | inch = 2.54 * centimeter = in = international_inch = inches = international_inches | 142 | inch = 2.54 * centimeter = in = international_inch = inches = international_inches |
2262 | 143 | foot = 12 * inch = ft = international_foot = feet = international_feet | 143 | foot = 12 * inch = ft = international_foot = feet = international_feet |
2263 | 144 | mile = 5280 * foot = mi = international_mile | 144 | mile = 5280 * foot = mi = international_mile |
2264 | @@ -291,7 +291,7 @@ | |||
2265 | 291 | pint = quart / 2 = pt = liquid_pint = US_liquid_pint | 291 | pint = quart / 2 = pt = liquid_pint = US_liquid_pint |
2266 | 292 | cup = pint / 2 = liquid_cup = US_liquid_cup | 292 | cup = pint / 2 = liquid_cup = US_liquid_cup |
2267 | 293 | gill = cup / 2 = liquid_gill = US_liquid_gill | 293 | gill = cup / 2 = liquid_gill = US_liquid_gill |
2269 | 294 | floz = gill / 4 = fluid_ounce = US_fluid_ounce = US_liquid_ounce | 294 | fluid_ounce = gill / 4 = floz = US_fluid_ounce = US_liquid_ounce |
2270 | 295 | imperial_bushel = 36.36872 * liter = UK_bushel | 295 | imperial_bushel = 36.36872 * liter = UK_bushel |
2271 | 296 | imperial_gallon = imperial_bushel / 8 = UK_gallon | 296 | imperial_gallon = imperial_bushel / 8 = UK_gallon |
2272 | 297 | imperial_quart = imperial_gallon / 4 = UK_quart | 297 | imperial_quart = imperial_gallon / 4 = UK_quart |
2273 | @@ -318,3 +318,33 @@ | |||
2274 | 318 | [temperature] -> [energy]: boltzmann_constant * value | 318 | [temperature] -> [energy]: boltzmann_constant * value |
2275 | 319 | [energy] -> [temperature]: value / boltzmann_constant | 319 | [energy] -> [temperature]: value / boltzmann_constant |
2276 | 320 | @end | 320 | @end |
2277 | 321 | |||
2278 | 322 | @context(mw=0,volume=0,solvent_mass=0) chemistry = chem | ||
2279 | 323 | # mw is the molecular weight of the species | ||
2280 | 324 | # volume is the volume of the solution | ||
2281 | 325 | # solvent_mass is the mass of solvent in the solution | ||
2282 | 326 | |||
2283 | 327 | # moles -> mass require the molecular weight | ||
2284 | 328 | [substance] -> [mass]: value * mw | ||
2285 | 329 | [mass] -> [substance]: value / mw | ||
2286 | 330 | |||
2287 | 331 | # moles/volume -> mass/volume and moles/mass -> mass / mass | ||
2288 | 332 | # require the molecular weight | ||
2289 | 333 | [substance] / [volume] -> [mass] / [volume]: value * mw | ||
2290 | 334 | [mass] / [volume] -> [substance] / [volume]: value / mw | ||
2291 | 335 | [substance] / [mass] -> [mass] / [mass]: value * mw | ||
2292 | 336 | [mass] / [mass] -> [substance] / [mass]: value / mw | ||
2293 | 337 | |||
2294 | 338 | # moles/volume -> moles requires the solution volume | ||
2295 | 339 | [substance] / [volume] -> [substance]: value * volume | ||
2296 | 340 | [substance] -> [substance] / [volume]: value / volume | ||
2297 | 341 | |||
2298 | 342 | # moles/mass -> moles requires the solvent (usually water) mass | ||
2299 | 343 | [substance] / [mass] -> [substance]: value * solvent_mass | ||
2300 | 344 | [substance] -> [substance] / [mass]: value / solvent_mass | ||
2301 | 345 | |||
2302 | 346 | # moles/mass -> moles/volume require the solvent mass and the volume | ||
2303 | 347 | [substance] / [mass] -> [substance]/[volume]: value * solvent_mass / volume | ||
2304 | 348 | [substance] / [volume] -> [substance] / [mass]: value / solvent_mass * volume | ||
2305 | 349 | |||
2306 | 350 | @end | ||
2307 | 321 | 351 | ||
2308 | === modified file 'pint/quantity.py' | |||
2309 | --- pint/quantity.py 2014-09-05 23:26:05 +0000 | |||
2310 | +++ pint/quantity.py 2015-01-07 15:51:38 +0000 | |||
2311 | @@ -15,7 +15,8 @@ | |||
2312 | 15 | import functools | 15 | import functools |
2313 | 16 | 16 | ||
2314 | 17 | from .formatting import remove_custom_flags | 17 | from .formatting import remove_custom_flags |
2316 | 18 | from .unit import DimensionalityError, UnitsContainer, UnitDefinition, UndefinedUnitError | 18 | from .unit import (DimensionalityError, OffsetUnitCalculusError, |
2317 | 19 | UnitsContainer, UnitDefinition, UndefinedUnitError) | ||
2318 | 19 | from .compat import string_types, ndarray, np, _to_magnitude, long_type | 20 | from .compat import string_types, ndarray, np, _to_magnitude, long_type |
2319 | 20 | from .util import logger | 21 | from .util import logger |
2320 | 21 | 22 | ||
2321 | @@ -48,6 +49,8 @@ | |||
2322 | 48 | # Both quantities are the same class and therefore from the same registry. | 49 | # Both quantities are the same class and therefore from the same registry. |
2323 | 49 | # (Each registry has its own Quantity class) | 50 | # (Each registry has its own Quantity class) |
2324 | 50 | return True | 51 | return True |
2325 | 52 | elif q1._REGISTRY is getattr(other, '_REGISTRY', None): | ||
2326 | 53 | return True | ||
2327 | 51 | elif isinstance(other, _Quantity): | 54 | elif isinstance(other, _Quantity): |
2328 | 52 | # The other object is a Quantity but from another registry. | 55 | # The other object is a Quantity but from another registry. |
2329 | 53 | raise ValueError('Cannot operate between quantities of different registries') | 56 | raise ValueError('Cannot operate between quantities of different registries') |
2330 | @@ -55,21 +58,8 @@ | |||
2331 | 55 | return False | 58 | return False |
2332 | 56 | 59 | ||
2333 | 57 | 60 | ||
2334 | 58 | def _only_multiplicative_units(q): | ||
2335 | 59 | """Check if the quantity has non-multiplicative units. | ||
2336 | 60 | """ | ||
2337 | 61 | |||
2338 | 62 | # Compound units are never multiplicative | ||
2339 | 63 | if len(q.units) != 1: | ||
2340 | 64 | return True | ||
2341 | 65 | |||
2342 | 66 | unit = list(q.units.keys())[0] | ||
2343 | 67 | |||
2344 | 68 | return q._REGISTRY._units[unit].is_multiplicative | ||
2345 | 69 | |||
2346 | 70 | |||
2347 | 71 | class _Quantity(object): | 61 | class _Quantity(object): |
2349 | 72 | """Implements a class to describe a physical quantities: | 62 | """Implements a class to describe a physical quantity: |
2350 | 73 | the product of a numerical value and a unit of measurement. | 63 | the product of a numerical value and a unit of measurement. |
2351 | 74 | 64 | ||
2352 | 75 | :param value: value of the physical quantity to be created. | 65 | :param value: value of the physical quantity to be created. |
2353 | @@ -138,7 +128,7 @@ | |||
2354 | 138 | spec = spec or self.default_format | 128 | spec = spec or self.default_format |
2355 | 139 | 129 | ||
2356 | 140 | if '~' in spec: | 130 | if '~' in spec: |
2358 | 141 | units = UnitsContainer(dict((self._REGISTRY.get_symbol(key), value) | 131 | units = UnitsContainer(dict((self._REGISTRY._get_symbol(key), value) |
2359 | 142 | for key, value in self.units.items())) | 132 | for key, value in self.units.items())) |
2360 | 143 | spec = spec.replace('~', '') | 133 | spec = spec.replace('~', '') |
2361 | 144 | else: | 134 | else: |
2362 | @@ -304,15 +294,8 @@ | |||
2363 | 304 | :param op: operator function (e.g. operator.add, operator.isub) | 294 | :param op: operator function (e.g. operator.add, operator.isub) |
2364 | 305 | :type op: function | 295 | :type op: function |
2365 | 306 | """ | 296 | """ |
2375 | 307 | if _check(self, other): | 297 | if not _check(self, other): |
2376 | 308 | if not self.dimensionality == other.dimensionality: | 298 | # other not from same Registry or not a Quantity |
2368 | 309 | raise DimensionalityError(self.units, other.units, | ||
2369 | 310 | self.dimensionality, other.dimensionality) | ||
2370 | 311 | if self._units == other._units: | ||
2371 | 312 | self._magnitude = op(self._magnitude, other._magnitude) | ||
2372 | 313 | else: | ||
2373 | 314 | self._magnitude = op(self._magnitude, other.to(self)._magnitude) | ||
2374 | 315 | else: | ||
2377 | 316 | try: | 299 | try: |
2378 | 317 | other_magnitude = _to_magnitude(other, self.force_ndarray) | 300 | other_magnitude = _to_magnitude(other, self.force_ndarray) |
2379 | 318 | except TypeError: | 301 | except TypeError: |
2380 | @@ -328,6 +311,75 @@ | |||
2381 | 328 | self._magnitude = op(self._magnitude, other_magnitude) | 311 | self._magnitude = op(self._magnitude, other_magnitude) |
2382 | 329 | else: | 312 | else: |
2383 | 330 | raise DimensionalityError(self.units, 'dimensionless') | 313 | raise DimensionalityError(self.units, 'dimensionless') |
2384 | 314 | return self | ||
2385 | 315 | |||
2386 | 316 | if not self.dimensionality == other.dimensionality: | ||
2387 | 317 | raise DimensionalityError(self.units, other.units, | ||
2388 | 318 | self.dimensionality, | ||
2389 | 319 | other.dimensionality) | ||
2390 | 320 | |||
2391 | 321 | # Next we define some variables to make if-clauses more readable. | ||
2392 | 322 | self_non_mul_units = self._get_non_multiplicative_units() | ||
2393 | 323 | is_self_multiplicative = len(self_non_mul_units) == 0 | ||
2394 | 324 | if len(self_non_mul_units) == 1: | ||
2395 | 325 | self_non_mul_unit = self_non_mul_units[0] | ||
2396 | 326 | other_non_mul_units = other._get_non_multiplicative_units() | ||
2397 | 327 | is_other_multiplicative = len(other_non_mul_units) == 0 | ||
2398 | 328 | if len(other_non_mul_units) == 1: | ||
2399 | 329 | other_non_mul_unit = other_non_mul_units[0] | ||
2400 | 330 | |||
2401 | 331 | # Presence of non-multiplicative units gives rise to several cases. | ||
2402 | 332 | if is_self_multiplicative and is_other_multiplicative: | ||
2403 | 333 | if self._units == other._units: | ||
2404 | 334 | self._magnitude = op(self._magnitude, other._magnitude) | ||
2405 | 335 | # If only self has a delta unit, other determines unit of result. | ||
2406 | 336 | elif self._get_delta_units() and not other._get_delta_units(): | ||
2407 | 337 | self._magnitude = op(self._convert_magnitude(other.units), | ||
2408 | 338 | other._magnitude) | ||
2409 | 339 | self._units = copy.copy(other.units) | ||
2410 | 340 | else: | ||
2411 | 341 | self._magnitude = op(self._magnitude, | ||
2412 | 342 | other.to(self.units)._magnitude) | ||
2413 | 343 | |||
2414 | 344 | elif (op == operator.isub and len(self_non_mul_units) == 1 | ||
2415 | 345 | and self.units[self_non_mul_unit] == 1 | ||
2416 | 346 | and not other._has_compatible_delta(self_non_mul_unit)): | ||
2417 | 347 | if self.units == other.units: | ||
2418 | 348 | self._magnitude = op(self._magnitude, other._magnitude) | ||
2419 | 349 | else: | ||
2420 | 350 | self._magnitude = op(self._magnitude, | ||
2421 | 351 | other.to(self.units)._magnitude) | ||
2422 | 352 | self.units['delta_' + self_non_mul_unit | ||
2423 | 353 | ] = self.units.pop(self_non_mul_unit) | ||
2424 | 354 | |||
2425 | 355 | elif (op == operator.isub and len(other_non_mul_units) == 1 | ||
2426 | 356 | and other.units[other_non_mul_unit] == 1 | ||
2427 | 357 | and not self._has_compatible_delta(other_non_mul_unit)): | ||
2428 | 358 | # we convert to self directly since it is multiplicative | ||
2429 | 359 | self._magnitude = op(self._magnitude, | ||
2430 | 360 | other.to(self.units)._magnitude) | ||
2431 | 361 | |||
2432 | 362 | elif (len(self_non_mul_units) == 1 | ||
2433 | 363 | # order of the dimension of offset unit == 1 ? | ||
2434 | 364 | and self._units[self_non_mul_unit] == 1 | ||
2435 | 365 | and other._has_compatible_delta(self_non_mul_unit)): | ||
2436 | 366 | tu = copy.copy(self.units) | ||
2437 | 367 | # Replace offset unit in self by the corresponding delta unit. | ||
2438 | 368 | # This is done to prevent a shift by offset in the to()-call. | ||
2439 | 369 | tu['delta_' + self_non_mul_unit] = tu.pop(self_non_mul_unit) | ||
2440 | 370 | self._magnitude = op(self._magnitude, other.to(tu)._magnitude) | ||
2441 | 371 | elif (len(other_non_mul_units) == 1 | ||
2442 | 372 | # order of the dimension of offset unit == 1 ? | ||
2443 | 373 | and other._units[other_non_mul_unit] == 1 | ||
2444 | 374 | and self._has_compatible_delta(other_non_mul_unit)): | ||
2445 | 375 | tu = copy.copy(other.units) | ||
2446 | 376 | # Replace offset unit in other by the corresponding delta unit. | ||
2447 | 377 | # This is done to prevent a shift by offset in the to()-call. | ||
2448 | 378 | tu['delta_' + other_non_mul_unit] = tu.pop(other_non_mul_unit) | ||
2449 | 379 | self._magnitude = op(self._convert_magnitude(tu), other._magnitude) | ||
2450 | 380 | self._units = copy.copy(other.units) | ||
2451 | 381 | else: | ||
2452 | 382 | raise OffsetUnitCalculusError(self.units, other.units) | ||
2453 | 331 | 383 | ||
2454 | 332 | return self | 384 | return self |
2455 | 333 | 385 | ||
2456 | @@ -339,17 +391,8 @@ | |||
2457 | 339 | :param op: operator function (e.g. operator.add, operator.isub) | 391 | :param op: operator function (e.g. operator.add, operator.isub) |
2458 | 340 | :type op: function | 392 | :type op: function |
2459 | 341 | """ | 393 | """ |
2471 | 342 | if _check(self, other): | 394 | if not _check(self, other): |
2472 | 343 | if not self.dimensionality == other.dimensionality: | 395 | # other not from same Registry or not a Quantity |
2462 | 344 | raise DimensionalityError(self.units, other.units, | ||
2463 | 345 | self.dimensionality, other.dimensionality) | ||
2464 | 346 | if self._units == other._units: | ||
2465 | 347 | magnitude = op(self._magnitude, other._magnitude) | ||
2466 | 348 | else: | ||
2467 | 349 | magnitude = op(self._magnitude, other.to(self)._magnitude) | ||
2468 | 350 | |||
2469 | 351 | units = copy.copy(self.units) | ||
2470 | 352 | else: | ||
2473 | 353 | if _eq(other, 0, True): | 396 | if _eq(other, 0, True): |
2474 | 354 | # If the other value is 0 (but not Quantity 0) | 397 | # If the other value is 0 (but not Quantity 0) |
2475 | 355 | # do the operation without checking units. | 398 | # do the operation without checking units. |
2476 | @@ -364,6 +407,79 @@ | |||
2477 | 364 | _to_magnitude(other, self.force_ndarray)) | 407 | _to_magnitude(other, self.force_ndarray)) |
2478 | 365 | else: | 408 | else: |
2479 | 366 | raise DimensionalityError(self.units, 'dimensionless') | 409 | raise DimensionalityError(self.units, 'dimensionless') |
2480 | 410 | return self.__class__(magnitude, units) | ||
2481 | 411 | |||
2482 | 412 | if not self.dimensionality == other.dimensionality: | ||
2483 | 413 | raise DimensionalityError(self.units, other.units, | ||
2484 | 414 | self.dimensionality, | ||
2485 | 415 | other.dimensionality) | ||
2486 | 416 | |||
2487 | 417 | # Next we define some variables to make if-clauses more readable. | ||
2488 | 418 | self_non_mul_units = self._get_non_multiplicative_units() | ||
2489 | 419 | is_self_multiplicative = len(self_non_mul_units) == 0 | ||
2490 | 420 | if len(self_non_mul_units) == 1: | ||
2491 | 421 | self_non_mul_unit = self_non_mul_units[0] | ||
2492 | 422 | other_non_mul_units = other._get_non_multiplicative_units() | ||
2493 | 423 | is_other_multiplicative = len(other_non_mul_units) == 0 | ||
2494 | 424 | if len(other_non_mul_units) == 1: | ||
2495 | 425 | other_non_mul_unit = other_non_mul_units[0] | ||
2496 | 426 | |||
2497 | 427 | # Presence of non-multiplicative units gives rise to several cases. | ||
2498 | 428 | if is_self_multiplicative and is_other_multiplicative: | ||
2499 | 429 | if self._units == other._units: | ||
2500 | 430 | magnitude = op(self._magnitude, other._magnitude) | ||
2501 | 431 | units = copy.copy(self.units) | ||
2502 | 432 | # If only self has a delta unit, other determines unit of result. | ||
2503 | 433 | elif self._get_delta_units() and not other._get_delta_units(): | ||
2504 | 434 | magnitude = op(self._convert_magnitude(other.units), | ||
2505 | 435 | other._magnitude) | ||
2506 | 436 | units = copy.copy(other.units) | ||
2507 | 437 | else: | ||
2508 | 438 | units = copy.copy(self.units) | ||
2509 | 439 | magnitude = op(self._magnitude, | ||
2510 | 440 | other.to(self.units).magnitude) | ||
2511 | 441 | |||
2512 | 442 | elif (op == operator.sub and len(self_non_mul_units) == 1 | ||
2513 | 443 | and self.units[self_non_mul_unit] == 1 | ||
2514 | 444 | and not other._has_compatible_delta(self_non_mul_unit)): | ||
2515 | 445 | if self.units == other.units: | ||
2516 | 446 | magnitude = op(self._magnitude, other._magnitude) | ||
2517 | 447 | else: | ||
2518 | 448 | magnitude = op(self._magnitude, | ||
2519 | 449 | other.to(self.units)._magnitude) | ||
2520 | 450 | units = copy.copy(self.units) | ||
2521 | 451 | units['delta_' + self_non_mul_unit] = units.pop(self_non_mul_unit) | ||
2522 | 452 | |||
2523 | 453 | elif (op == operator.sub and len(other_non_mul_units) == 1 | ||
2524 | 454 | and other.units[other_non_mul_unit] == 1 | ||
2525 | 455 | and not self._has_compatible_delta(other_non_mul_unit)): | ||
2526 | 456 | # we convert to self directly since it is multiplicative | ||
2527 | 457 | magnitude = op(self._magnitude, | ||
2528 | 458 | other.to(self.units)._magnitude) | ||
2529 | 459 | units = copy.copy(self.units) | ||
2530 | 460 | |||
2531 | 461 | elif (len(self_non_mul_units) == 1 | ||
2532 | 462 | # order of the dimension of offset unit == 1 ? | ||
2533 | 463 | and self._units[self_non_mul_unit] == 1 | ||
2534 | 464 | and other._has_compatible_delta(self_non_mul_unit)): | ||
2535 | 465 | tu = copy.copy(self.units) | ||
2536 | 466 | # Replace offset unit in self by the corresponding delta unit. | ||
2537 | 467 | # This is done to prevent a shift by offset in the to()-call. | ||
2538 | 468 | tu['delta_' + self_non_mul_unit] = tu.pop(self_non_mul_unit) | ||
2539 | 469 | magnitude = op(self._magnitude, other.to(tu).magnitude) | ||
2540 | 470 | units = copy.copy(self.units) | ||
2541 | 471 | elif (len(other_non_mul_units) == 1 | ||
2542 | 472 | # order of the dimension of offset unit == 1 ? | ||
2543 | 473 | and other._units[other_non_mul_unit] == 1 | ||
2544 | 474 | and self._has_compatible_delta(other_non_mul_unit)): | ||
2545 | 475 | tu = copy.copy(other.units) | ||
2546 | 476 | # Replace offset unit in other by the corresponding delta unit. | ||
2547 | 477 | # This is done to prevent a shift by offset in the to()-call. | ||
2548 | 478 | tu['delta_' + other_non_mul_unit] = tu.pop(other_non_mul_unit) | ||
2549 | 479 | magnitude = op(self._convert_magnitude(tu), other._magnitude) | ||
2550 | 480 | units = copy.copy(other.units) | ||
2551 | 481 | else: | ||
2552 | 482 | raise OffsetUnitCalculusError(self.units, other.units) | ||
2553 | 367 | 483 | ||
2554 | 368 | return self.__class__(magnitude, units) | 484 | return self.__class__(magnitude, units) |
2555 | 369 | 485 | ||
2556 | @@ -403,24 +519,40 @@ | |||
2557 | 403 | if units_op is None: | 519 | if units_op is None: |
2558 | 404 | units_op = magnitude_op | 520 | units_op = magnitude_op |
2559 | 405 | 521 | ||
2565 | 406 | if self.__used: | 522 | offset_units_self = self._get_non_multiplicative_units() |
2566 | 407 | if not _only_multiplicative_units(self): | 523 | no_offset_units_self = len(offset_units_self) |
2562 | 408 | self.ito_base_units() | ||
2563 | 409 | else: | ||
2564 | 410 | self.__used = True | ||
2567 | 411 | 524 | ||
2574 | 412 | if _check(self, other): | 525 | if not _check(self, other): |
2575 | 413 | if not _only_multiplicative_units(other): | 526 | if not self._ok_for_muldiv(no_offset_units_self): |
2576 | 414 | other = other.to_base_units() | 527 | raise OffsetUnitCalculusError(self.units, |
2577 | 415 | self._magnitude = magnitude_op(self._magnitude, other._magnitude) | 528 | getattr(other, 'units', '')) |
2578 | 416 | self._units = units_op(self._units, other._units) | 529 | if len(offset_units_self) == 1: |
2579 | 417 | else: | 530 | if (self.units[offset_units_self[0]] != 1 |
2580 | 531 | or magnitude_op not in [operator.mul, operator.imul]): | ||
2581 | 532 | raise OffsetUnitCalculusError(self.units, | ||
2582 | 533 | getattr(other, 'units', '')) | ||
2583 | 418 | try: | 534 | try: |
2584 | 419 | other_magnitude = _to_magnitude(other, self.force_ndarray) | 535 | other_magnitude = _to_magnitude(other, self.force_ndarray) |
2585 | 420 | except TypeError: | 536 | except TypeError: |
2586 | 421 | return NotImplemented | 537 | return NotImplemented |
2587 | 422 | self._magnitude = magnitude_op(self._magnitude, other_magnitude) | 538 | self._magnitude = magnitude_op(self._magnitude, other_magnitude) |
2588 | 423 | self._units = units_op(self._units, UnitsContainer()) | 539 | self._units = units_op(self._units, UnitsContainer()) |
2589 | 540 | return self | ||
2590 | 541 | |||
2591 | 542 | if not self._ok_for_muldiv(no_offset_units_self): | ||
2592 | 543 | raise OffsetUnitCalculusError(self.units, other.units) | ||
2593 | 544 | elif no_offset_units_self == 1 and len(self.units) == 1: | ||
2594 | 545 | self.ito_base_units() | ||
2595 | 546 | |||
2596 | 547 | no_offset_units_other = len(other._get_non_multiplicative_units()) | ||
2597 | 548 | |||
2598 | 549 | if not other._ok_for_muldiv(no_offset_units_other): | ||
2599 | 550 | raise OffsetUnitCalculusError(self.units, other.units) | ||
2600 | 551 | elif no_offset_units_other == 1 and len(other.units) == 1: | ||
2601 | 552 | other.ito_base_units() | ||
2602 | 553 | |||
2603 | 554 | self._magnitude = magnitude_op(self._magnitude, other._magnitude) | ||
2604 | 555 | self._units = units_op(self._units, other._units) | ||
2605 | 424 | 556 | ||
2606 | 425 | return self | 557 | return self |
2607 | 426 | 558 | ||
2608 | @@ -437,27 +569,46 @@ | |||
2609 | 437 | if units_op is None: | 569 | if units_op is None: |
2610 | 438 | units_op = magnitude_op | 570 | units_op = magnitude_op |
2611 | 439 | 571 | ||
2612 | 572 | offset_units_self = self._get_non_multiplicative_units() | ||
2613 | 573 | no_offset_units_self = len(offset_units_self) | ||
2614 | 574 | |||
2615 | 575 | if not _check(self, other): | ||
2616 | 576 | if not self._ok_for_muldiv(no_offset_units_self): | ||
2617 | 577 | raise OffsetUnitCalculusError(self.units, | ||
2618 | 578 | getattr(other, 'units', '')) | ||
2619 | 579 | if len(offset_units_self) == 1: | ||
2620 | 580 | if (self.units[offset_units_self[0]] != 1 | ||
2621 | 581 | or magnitude_op not in [operator.mul, operator.imul]): | ||
2622 | 582 | raise OffsetUnitCalculusError(self.units, | ||
2623 | 583 | getattr(other, 'units', '')) | ||
2624 | 584 | try: | ||
2625 | 585 | other_magnitude = _to_magnitude(other, self.force_ndarray) | ||
2626 | 586 | except TypeError: | ||
2627 | 587 | return NotImplemented | ||
2628 | 588 | |||
2629 | 589 | magnitude = magnitude_op(self._magnitude, other_magnitude) | ||
2630 | 590 | units = units_op(self._units, UnitsContainer()) | ||
2631 | 591 | |||
2632 | 592 | return self.__class__(magnitude, units) | ||
2633 | 593 | |||
2634 | 440 | new_self = self | 594 | new_self = self |
2655 | 441 | if self.__used: | 595 | |
2656 | 442 | if not _only_multiplicative_units(self): | 596 | if not self._ok_for_muldiv(no_offset_units_self): |
2657 | 443 | new_self = self.to_base_units() | 597 | raise OffsetUnitCalculusError(self.units, other.units) |
2658 | 444 | 598 | elif no_offset_units_self == 1 and len(self.units) == 1: | |
2659 | 445 | if _check(self, other): | 599 | new_self = self.to_base_units() |
2660 | 446 | if not _only_multiplicative_units(other): | 600 | |
2661 | 447 | other = other.to_base_units() | 601 | no_offset_units_other = len(other._get_non_multiplicative_units()) |
2662 | 448 | magnitude = magnitude_op(new_self._magnitude, other._magnitude) | 602 | |
2663 | 449 | units = units_op(new_self._units, other._units) | 603 | if not other._ok_for_muldiv(no_offset_units_other): |
2664 | 450 | else: | 604 | raise OffsetUnitCalculusError(self.units, other.units) |
2665 | 451 | try: | 605 | elif no_offset_units_other == 1 and len(other.units) == 1: |
2666 | 452 | other_magnitude = _to_magnitude(other, self.force_ndarray) | 606 | other = other.to_base_units() |
2667 | 453 | except TypeError: | 607 | |
2668 | 454 | return NotImplemented | 608 | magnitude = magnitude_op(new_self._magnitude, other._magnitude) |
2669 | 455 | magnitude = magnitude_op(new_self._magnitude, other_magnitude) | 609 | units = units_op(new_self._units, other._units) |
2670 | 456 | units = units_op(new_self._units, UnitsContainer()) | 610 | |
2671 | 457 | 611 | return self.__class__(magnitude, units) | |
2652 | 458 | ret = self.__class__(magnitude, units) | ||
2653 | 459 | ret.__used = True | ||
2654 | 460 | return ret | ||
2672 | 461 | 612 | ||
2673 | 462 | def __imul__(self, other): | 613 | def __imul__(self, other): |
2674 | 463 | if not isinstance(self._magnitude, ndarray): | 614 | if not isinstance(self._magnitude, ndarray): |
2675 | @@ -493,6 +644,13 @@ | |||
2676 | 493 | other_magnitude = _to_magnitude(other, self.force_ndarray) | 644 | other_magnitude = _to_magnitude(other, self.force_ndarray) |
2677 | 494 | except TypeError: | 645 | except TypeError: |
2678 | 495 | return NotImplemented | 646 | return NotImplemented |
2679 | 647 | |||
2680 | 648 | no_offset_units_self = len(self._get_non_multiplicative_units()) | ||
2681 | 649 | if not self._ok_for_muldiv(no_offset_units_self): | ||
2682 | 650 | raise OffsetUnitCalculusError(self.units, '') | ||
2683 | 651 | elif no_offset_units_self == 1 and len(self.units) == 1: | ||
2684 | 652 | self = self.to_base_units() | ||
2685 | 653 | |||
2686 | 496 | return self.__class__(other_magnitude / self._magnitude, 1 / self._units) | 654 | return self.__class__(other_magnitude / self._magnitude, 1 / self._units) |
2687 | 497 | 655 | ||
2688 | 498 | def __rfloordiv__(self, other): | 656 | def __rfloordiv__(self, other): |
2689 | @@ -500,6 +658,13 @@ | |||
2690 | 500 | other_magnitude = _to_magnitude(other, self.force_ndarray) | 658 | other_magnitude = _to_magnitude(other, self.force_ndarray) |
2691 | 501 | except TypeError: | 659 | except TypeError: |
2692 | 502 | return NotImplemented | 660 | return NotImplemented |
2693 | 661 | |||
2694 | 662 | no_offset_units_self = len(self._get_non_multiplicative_units()) | ||
2695 | 663 | if not self._ok_for_muldiv(no_offset_units_self): | ||
2696 | 664 | raise OffsetUnitCalculusError(self.units, '') | ||
2697 | 665 | elif no_offset_units_self == 1 and len(self.units) == 1: | ||
2698 | 666 | self = self.to_base_units() | ||
2699 | 667 | |||
2700 | 503 | return self.__class__(other_magnitude // self._magnitude, 1 / self._units) | 668 | return self.__class__(other_magnitude // self._magnitude, 1 / self._units) |
2701 | 504 | 669 | ||
2702 | 505 | __div__ = __truediv__ | 670 | __div__ = __truediv__ |
2703 | @@ -515,10 +680,36 @@ | |||
2704 | 515 | except TypeError: | 680 | except TypeError: |
2705 | 516 | return NotImplemented | 681 | return NotImplemented |
2706 | 517 | else: | 682 | else: |
2709 | 518 | if not _only_multiplicative_units(self): | 683 | if not self._ok_for_muldiv: |
2710 | 519 | self.ito_base_units() | 684 | raise OffsetUnitCalculusError(self.units) |
2711 | 685 | |||
2712 | 686 | if isinstance(getattr(other, '_magnitude', other), ndarray): | ||
2713 | 687 | # arrays are refused as exponent, because they would create | ||
2714 | 688 | # len(array) quanitites of len(set(array)) different units | ||
2715 | 689 | if np.size(other) > 1: | ||
2716 | 690 | raise DimensionalityError(self.units, 'dimensionless') | ||
2717 | 691 | |||
2718 | 692 | new_self = self | ||
2719 | 693 | if other == 1: | ||
2720 | 694 | return self | ||
2721 | 695 | elif other == 0: | ||
2722 | 696 | self._units = UnitsContainer() | ||
2723 | 697 | else: | ||
2724 | 698 | if not self._is_multiplicative: | ||
2725 | 699 | if self._REGISTRY.autoconvert_offset_to_baseunit: | ||
2726 | 700 | self.ito_base_units() | ||
2727 | 701 | else: | ||
2728 | 702 | raise OffsetUnitCalculusError(self.units) | ||
2729 | 703 | |||
2730 | 704 | if getattr(other, 'dimensionless', False): | ||
2731 | 705 | other = other.to_base_units() | ||
2732 | 706 | self._units **= other.magnitude | ||
2733 | 707 | elif not getattr(other, 'dimensionless', True): | ||
2734 | 708 | raise DimensionalityError(self.units, 'dimensionless') | ||
2735 | 709 | else: | ||
2736 | 710 | self._units **= other | ||
2737 | 711 | |||
2738 | 520 | self._magnitude **= _to_magnitude(other, self.force_ndarray) | 712 | self._magnitude **= _to_magnitude(other, self.force_ndarray) |
2739 | 521 | self._units **= other | ||
2740 | 522 | return self | 713 | return self |
2741 | 523 | 714 | ||
2742 | 524 | def __pow__(self, other): | 715 | def __pow__(self, other): |
2743 | @@ -527,14 +718,51 @@ | |||
2744 | 527 | except TypeError: | 718 | except TypeError: |
2745 | 528 | return NotImplemented | 719 | return NotImplemented |
2746 | 529 | else: | 720 | else: |
2747 | 721 | if not self._ok_for_muldiv: | ||
2748 | 722 | raise OffsetUnitCalculusError(self.units) | ||
2749 | 723 | |||
2750 | 724 | if isinstance(getattr(other, '_magnitude', other), ndarray): | ||
2751 | 725 | # arrays are refused as exponent, because they would create | ||
2752 | 726 | # len(array) quantities of len(set(array)) different units | ||
2753 | 727 | if np.size(other) > 1: | ||
2754 | 728 | raise DimensionalityError(self.units, 'dimensionless') | ||
2755 | 729 | |||
2756 | 530 | new_self = self | 730 | new_self = self |
2759 | 531 | if not _only_multiplicative_units(self): | 731 | if other == 1: |
2760 | 532 | new_self = self.to_base_units() | 732 | return self |
2761 | 733 | elif other == 0: | ||
2762 | 734 | units = UnitsContainer() | ||
2763 | 735 | else: | ||
2764 | 736 | if not self._is_multiplicative: | ||
2765 | 737 | if self._REGISTRY.autoconvert_offset_to_baseunit: | ||
2766 | 738 | new_self = self.to_base_units() | ||
2767 | 739 | else: | ||
2768 | 740 | raise OffsetUnitCalculusError(self.units) | ||
2769 | 741 | |||
2770 | 742 | if getattr(other, 'dimensionless', False): | ||
2771 | 743 | units = new_self._units ** other.to_base_units().magnitude | ||
2772 | 744 | elif not getattr(other, 'dimensionless', True): | ||
2773 | 745 | raise DimensionalityError(self.units, 'dimensionless') | ||
2774 | 746 | else: | ||
2775 | 747 | units = new_self._units ** other | ||
2776 | 533 | 748 | ||
2777 | 534 | magnitude = new_self._magnitude ** _to_magnitude(other, self.force_ndarray) | 749 | magnitude = new_self._magnitude ** _to_magnitude(other, self.force_ndarray) |
2778 | 535 | units = new_self._units ** other | ||
2779 | 536 | return self.__class__(magnitude, units) | 750 | return self.__class__(magnitude, units) |
2780 | 537 | 751 | ||
2781 | 752 | def __rpow__(self, other): | ||
2782 | 753 | try: | ||
2783 | 754 | other_magnitude = _to_magnitude(other, self.force_ndarray) | ||
2784 | 755 | except TypeError: | ||
2785 | 756 | return NotImplemented | ||
2786 | 757 | else: | ||
2787 | 758 | if not self.dimensionless: | ||
2788 | 759 | raise DimensionalityError(self.units, 'dimensionless') | ||
2789 | 760 | if isinstance(self._magnitude, ndarray): | ||
2790 | 761 | if np.size(self._magnitude) > 1: | ||
2791 | 762 | raise DimensionalityError(self.units, 'dimensionless') | ||
2792 | 763 | new_self = self.to_base_units() | ||
2793 | 764 | return other**new_self._magnitude | ||
2794 | 765 | |||
2795 | 538 | def __abs__(self): | 766 | def __abs__(self): |
2796 | 539 | return self.__class__(abs(self._magnitude), self._units) | 767 | return self.__class__(abs(self._magnitude), self._units) |
2797 | 540 | 768 | ||
2798 | @@ -798,7 +1026,10 @@ | |||
2799 | 798 | 1026 | ||
2800 | 799 | if isinstance(factor, self.__class__): | 1027 | if isinstance(factor, self.__class__): |
2801 | 800 | if not factor.dimensionless: | 1028 | if not factor.dimensionless: |
2803 | 801 | raise ValueError | 1029 | raise DimensionalityError(value, self.units, |
2804 | 1030 | extra_msg='. Assign a quantity with the same dimensionality or ' | ||
2805 | 1031 | 'access the magnitude directly as ' | ||
2806 | 1032 | '`obj.magnitude[%s] = %s`' % (key, value)) | ||
2807 | 802 | self._magnitude[key] = factor.magnitude | 1033 | self._magnitude[key] = factor.magnitude |
2808 | 803 | else: | 1034 | else: |
2809 | 804 | self._magnitude[key] = factor | 1035 | self._magnitude[key] = factor |
2810 | @@ -961,3 +1192,58 @@ | |||
2811 | 961 | error = error * abs(self.magnitude) | 1192 | error = error * abs(self.magnitude) |
2812 | 962 | 1193 | ||
2813 | 963 | return self._REGISTRY.Measurement(copy.copy(self.magnitude), error, self.units) | 1194 | return self._REGISTRY.Measurement(copy.copy(self.magnitude), error, self.units) |
2814 | 1195 | |||
2815 | 1196 | # methods/properties that help for math operations with offset units | ||
2816 | 1197 | @property | ||
2817 | 1198 | def _is_multiplicative(self): | ||
2818 | 1199 | """Check if the Quantity object has only multiplicative units. | ||
2819 | 1200 | """ | ||
2820 | 1201 | # XXX Turn this into a method/property of _Quantity? | ||
2821 | 1202 | return not self._get_non_multiplicative_units() | ||
2822 | 1203 | |||
2823 | 1204 | def _get_non_multiplicative_units(self): | ||
2824 | 1205 | """Return a list of the of non-multiplicative units of the Quantity object | ||
2825 | 1206 | """ | ||
2826 | 1207 | offset_units = [unit for unit in self.units.keys() | ||
2827 | 1208 | if not self._REGISTRY._units[unit].is_multiplicative] | ||
2828 | 1209 | return offset_units | ||
2829 | 1210 | |||
2830 | 1211 | def _get_delta_units(self): | ||
2831 | 1212 | """Return list of delta units ot the Quantity object | ||
2832 | 1213 | """ | ||
2833 | 1214 | delta_units = [u for u in self.units.keys() if u.startswith("delta_")] | ||
2834 | 1215 | return delta_units | ||
2835 | 1216 | |||
2836 | 1217 | def _has_compatible_delta(self, unit): | ||
2837 | 1218 | """"Check if Quantity object has a delta_unit that is compatible with unit | ||
2838 | 1219 | """ | ||
2839 | 1220 | deltas = self._get_delta_units() | ||
2840 | 1221 | if 'delta_' + unit in deltas: | ||
2841 | 1222 | return True | ||
2842 | 1223 | else: # Look for delta units with same dimension as the offset unit | ||
2843 | 1224 | offset_unit_dim = self._REGISTRY._units[unit].reference | ||
2844 | 1225 | for d in deltas: | ||
2845 | 1226 | if self._REGISTRY._units[d].reference == offset_unit_dim: | ||
2846 | 1227 | return True | ||
2847 | 1228 | return False | ||
2848 | 1229 | |||
2849 | 1230 | def _ok_for_muldiv(self, no_offset_units=None): | ||
2850 | 1231 | """Checks if Quantity object can be multiplied or divided | ||
2851 | 1232 | |||
2852 | 1233 | :q: quantity object that is checked | ||
2853 | 1234 | :no_offset_units: number of offset units in q | ||
2854 | 1235 | """ | ||
2855 | 1236 | is_ok = True | ||
2856 | 1237 | if no_offset_units is None: | ||
2857 | 1238 | no_offset_units = len(self._get_non_multiplicative_units()) | ||
2858 | 1239 | if no_offset_units > 1: | ||
2859 | 1240 | is_ok = False | ||
2860 | 1241 | if no_offset_units == 1: | ||
2861 | 1242 | if len(self._units) > 1: | ||
2862 | 1243 | is_ok = False | ||
2863 | 1244 | if (len(self._units) == 1 | ||
2864 | 1245 | and not self._REGISTRY.autoconvert_offset_to_baseunit): | ||
2865 | 1246 | is_ok = False | ||
2866 | 1247 | if next(iter(self._units.values())) != 1: | ||
2867 | 1248 | is_ok = False | ||
2868 | 1249 | return is_ok | ||
2869 | 964 | 1250 | ||
2870 | === added file 'pint/testsuite/parameterized.py' | |||
2871 | --- pint/testsuite/parameterized.py 1970-01-01 00:00:00 +0000 | |||
2872 | +++ pint/testsuite/parameterized.py 2015-01-07 15:51:38 +0000 | |||
2873 | @@ -0,0 +1,152 @@ | |||
2874 | 1 | # -*- coding: utf-8 -*- | ||
2875 | 2 | # | ||
2876 | 3 | # Adds Parameterized tests for Python's unittest module | ||
2877 | 4 | # | ||
2878 | 5 | # Code from: parameterizedtestcase, version: 0.1.0 | ||
2879 | 6 | # Homepage: https://github.com/msabramo/python_unittest_parameterized_test_case | ||
2880 | 7 | # Author: Marc Abramowitz, email: marc@marc-abramowitz.com | ||
2881 | 8 | # License: MIT | ||
2882 | 9 | # | ||
2883 | 10 | # Fixed for to work in Python 2 & 3 with "add_metaclass" decorator from six | ||
2884 | 11 | # https://pypi.python.org/pypi/six | ||
2885 | 12 | # Author: Benjamin Peterson | ||
2886 | 13 | # License: MIT | ||
2887 | 14 | # | ||
2888 | 15 | # Use like this: | ||
2889 | 16 | # | ||
2890 | 17 | # from parameterizedtestcase import ParameterizedTestCase | ||
2891 | 18 | # | ||
2892 | 19 | # class MyTests(ParameterizedTestCase): | ||
2893 | 20 | # @ParameterizedTestCase.parameterize( | ||
2894 | 21 | # ("input", "expected_output"), | ||
2895 | 22 | # [ | ||
2896 | 23 | # ("2+4", 6), | ||
2897 | 24 | # ("3+5", 8), | ||
2898 | 25 | # ("6*9", 54), | ||
2899 | 26 | # ] | ||
2900 | 27 | # ) | ||
2901 | 28 | # def test_eval(self, input, expected_output): | ||
2902 | 29 | # self.assertEqual(eval(input), expected_output) | ||
2903 | 30 | |||
2904 | 31 | try: | ||
2905 | 32 | import unittest2 as unittest | ||
2906 | 33 | except ImportError: # pragma: no cover | ||
2907 | 34 | import unittest | ||
2908 | 35 | |||
2909 | 36 | from functools import wraps | ||
2910 | 37 | import collections | ||
2911 | 38 | |||
2912 | 39 | |||
2913 | 40 | def add_metaclass(metaclass): | ||
2914 | 41 | """Class decorator for creating a class with a metaclass.""" | ||
2915 | 42 | def wrapper(cls): | ||
2916 | 43 | orig_vars = cls.__dict__.copy() | ||
2917 | 44 | orig_vars.pop('__dict__', None) | ||
2918 | 45 | orig_vars.pop('__weakref__', None) | ||
2919 | 46 | slots = orig_vars.get('__slots__') | ||
2920 | 47 | if slots is not None: | ||
2921 | 48 | if isinstance(slots, str): | ||
2922 | 49 | slots = [slots] | ||
2923 | 50 | for slots_var in slots: | ||
2924 | 51 | orig_vars.pop(slots_var) | ||
2925 | 52 | return metaclass(cls.__name__, cls.__bases__, orig_vars) | ||
2926 | 53 | return wrapper | ||
2927 | 54 | |||
2928 | 55 | |||
2929 | 56 | def augment_method_docstring(method, new_class_dict, classname, | ||
2930 | 57 | param_names, param_values, new_method): | ||
2931 | 58 | param_assignments_str = '; '.join( | ||
2932 | 59 | ['%s = %s' % (k, v) for (k, v) in zip(param_names, param_values)]) | ||
2933 | 60 | extra_doc = "%s (%s.%s) [with %s] " % ( | ||
2934 | 61 | method.__name__, new_class_dict.get('__module__', '<module>'), | ||
2935 | 62 | classname, param_assignments_str) | ||
2936 | 63 | |||
2937 | 64 | try: | ||
2938 | 65 | new_method.__doc__ = extra_doc + new_method.__doc__ | ||
2939 | 66 | except TypeError: # Catches when new_method.__doc__ is None | ||
2940 | 67 | new_method.__doc__ = extra_doc | ||
2941 | 68 | |||
2942 | 69 | |||
2943 | 70 | class ParameterizedTestCaseMetaClass(type): | ||
2944 | 71 | method_counter = {} | ||
2945 | 72 | |||
2946 | 73 | def __new__(meta, classname, bases, class_dict): | ||
2947 | 74 | new_class_dict = {} | ||
2948 | 75 | |||
2949 | 76 | for attr_name, attr_value in list(class_dict.items()): | ||
2950 | 77 | if isinstance(attr_value, collections.Callable) and hasattr(attr_value, 'param_names'): | ||
2951 | 78 | # print("Processing attr_name = %r; attr_value = %r" % ( | ||
2952 | 79 | # attr_name, attr_value)) | ||
2953 | 80 | |||
2954 | 81 | method = attr_value | ||
2955 | 82 | param_names = attr_value.param_names | ||
2956 | 83 | data = attr_value.data | ||
2957 | 84 | func_name_format = attr_value.func_name_format | ||
2958 | 85 | |||
2959 | 86 | meta.process_method( | ||
2960 | 87 | classname, method, param_names, data, new_class_dict, | ||
2961 | 88 | func_name_format) | ||
2962 | 89 | else: | ||
2963 | 90 | new_class_dict[attr_name] = attr_value | ||
2964 | 91 | |||
2965 | 92 | return type.__new__(meta, classname, bases, new_class_dict) | ||
2966 | 93 | |||
2967 | 94 | @classmethod | ||
2968 | 95 | def process_method( | ||
2969 | 96 | cls, classname, method, param_names, data, new_class_dict, | ||
2970 | 97 | func_name_format): | ||
2971 | 98 | method_counter = cls.method_counter | ||
2972 | 99 | |||
2973 | 100 | for param_values in data: | ||
2974 | 101 | new_method = cls.new_method(method, param_values) | ||
2975 | 102 | method_counter[method.__name__] = \ | ||
2976 | 103 | method_counter.get(method.__name__, 0) + 1 | ||
2977 | 104 | case_data = dict(list(zip(param_names, param_values))) | ||
2978 | 105 | case_data['func_name'] = method.__name__ | ||
2979 | 106 | case_data['case_num'] = method_counter[method.__name__] | ||
2980 | 107 | |||
2981 | 108 | new_method.__name__ = func_name_format.format(**case_data) | ||
2982 | 109 | |||
2983 | 110 | augment_method_docstring( | ||
2984 | 111 | method, new_class_dict, classname, | ||
2985 | 112 | param_names, param_values, new_method) | ||
2986 | 113 | new_class_dict[new_method.__name__] = new_method | ||
2987 | 114 | |||
2988 | 115 | @classmethod | ||
2989 | 116 | def new_method(cls, method, param_values): | ||
2990 | 117 | @wraps(method) | ||
2991 | 118 | def new_method(self): | ||
2992 | 119 | return method(self, *param_values) | ||
2993 | 120 | |||
2994 | 121 | return new_method | ||
2995 | 122 | |||
2996 | 123 | @add_metaclass(ParameterizedTestCaseMetaClass) | ||
2997 | 124 | class ParameterizedTestMixin(object): | ||
2998 | 125 | @classmethod | ||
2999 | 126 | def parameterize(cls, param_names, data, | ||
3000 | 127 | func_name_format='{func_name}_{case_num:05d}'): | ||
3001 | 128 | """Decorator for parameterizing a test method - example: | ||
3002 | 129 | |||
3003 | 130 | @ParameterizedTestCase.parameterize( | ||
3004 | 131 | ("isbn", "expected_title"), [ | ||
3005 | 132 | ("0262033844", "Introduction to Algorithms"), | ||
3006 | 133 | ("0321558146", "Campbell Essential Biology")]) | ||
3007 | 134 | |||
3008 | 135 | """ | ||
3009 | 136 | |||
3010 | 137 | def decorator(func): | ||
3011 | 138 | @wraps(func) | ||
3012 | 139 | def newfunc(*arg, **kwargs): | ||
3013 | 140 | return func(*arg, **kwargs) | ||
3014 | 141 | |||
3015 | 142 | newfunc.param_names = param_names | ||
3016 | 143 | newfunc.data = data | ||
3017 | 144 | newfunc.func_name_format = func_name_format | ||
3018 | 145 | |||
3019 | 146 | return newfunc | ||
3020 | 147 | |||
3021 | 148 | return decorator | ||
3022 | 149 | |||
3023 | 150 | @add_metaclass(ParameterizedTestCaseMetaClass) | ||
3024 | 151 | class ParameterizedTestCase(unittest.TestCase, ParameterizedTestMixin): | ||
3025 | 152 | pass | ||
3026 | 0 | 153 | ||
3027 | === modified file 'pint/testsuite/test_issues.py' | |||
3028 | --- pint/testsuite/test_issues.py 2014-09-05 23:26:05 +0000 | |||
3029 | +++ pint/testsuite/test_issues.py 2015-01-07 15:51:38 +0000 | |||
3030 | @@ -16,6 +16,9 @@ | |||
3031 | 16 | 16 | ||
3032 | 17 | FORCE_NDARRAY = False | 17 | FORCE_NDARRAY = False |
3033 | 18 | 18 | ||
3034 | 19 | def setup(self): | ||
3035 | 20 | self.ureg.autoconvert_offset_to_baseunit = False | ||
3036 | 21 | |||
3037 | 19 | @unittest.expectedFailure | 22 | @unittest.expectedFailure |
3038 | 20 | def test_issue25(self): | 23 | def test_issue25(self): |
3039 | 21 | x = ParserHelper.from_string('10 %') | 24 | x = ParserHelper.from_string('10 %') |
3040 | @@ -92,9 +95,9 @@ | |||
3041 | 92 | def test_issue66b(self): | 95 | def test_issue66b(self): |
3042 | 93 | ureg = UnitRegistry() | 96 | ureg = UnitRegistry() |
3043 | 94 | self.assertEqual(ureg.get_base_units(ureg.kelvin.units), | 97 | self.assertEqual(ureg.get_base_units(ureg.kelvin.units), |
3045 | 95 | (None, UnitsContainer({'kelvin': 1}))) | 98 | (1.0, UnitsContainer({'kelvin': 1}))) |
3046 | 96 | self.assertEqual(ureg.get_base_units(ureg.degC.units), | 99 | self.assertEqual(ureg.get_base_units(ureg.degC.units), |
3048 | 97 | (None, UnitsContainer({'kelvin': 1}))) | 100 | (1.0, UnitsContainer({'kelvin': 1}))) |
3049 | 98 | 101 | ||
3050 | 99 | def test_issue69(self): | 102 | def test_issue69(self): |
3051 | 100 | ureg = UnitRegistry() | 103 | ureg = UnitRegistry() |
3052 | @@ -127,11 +130,12 @@ | |||
3053 | 127 | self.assertQuantityAlmostEqual(va.to_base_units(), vb.to_base_units()) | 130 | self.assertQuantityAlmostEqual(va.to_base_units(), vb.to_base_units()) |
3054 | 128 | 131 | ||
3055 | 129 | def test_issue86(self): | 132 | def test_issue86(self): |
3056 | 133 | ureg = self.ureg | ||
3057 | 134 | ureg.autoconvert_offset_to_baseunit = True | ||
3058 | 135 | |||
3059 | 130 | def parts(q): | 136 | def parts(q): |
3060 | 131 | return q.magnitude, q.units | 137 | return q.magnitude, q.units |
3061 | 132 | 138 | ||
3062 | 133 | ureg = UnitRegistry() | ||
3063 | 134 | |||
3064 | 135 | q1 = 10. * ureg.degC | 139 | q1 = 10. * ureg.degC |
3065 | 136 | q2 = 10. * ureg.kelvin | 140 | q2 = 10. * ureg.kelvin |
3066 | 137 | 141 | ||
3067 | @@ -158,7 +162,6 @@ | |||
3068 | 158 | self.assertEqual(parts(q1 / q3), (k1m / q3m, k1u / q3u)) | 162 | self.assertEqual(parts(q1 / q3), (k1m / q3m, k1u / q3u)) |
3069 | 159 | self.assertEqual(parts(q3 * q1), (q3m * k1m, q3u * k1u)) | 163 | self.assertEqual(parts(q3 * q1), (q3m * k1m, q3u * k1u)) |
3070 | 160 | self.assertEqual(parts(q3 / q1), (q3m / k1m, q3u / k1u)) | 164 | self.assertEqual(parts(q3 / q1), (q3m / k1m, q3u / k1u)) |
3071 | 161 | self.assertEqual(parts(q1 ** 1), (k1m ** 1, k1u ** 1)) | ||
3072 | 162 | self.assertEqual(parts(q1 ** -1), (k1m ** -1, k1u ** -1)) | 165 | self.assertEqual(parts(q1 ** -1), (k1m ** -1, k1u ** -1)) |
3073 | 163 | self.assertEqual(parts(q1 ** 2), (k1m ** 2, k1u ** 2)) | 166 | self.assertEqual(parts(q1 ** 2), (k1m ** 2, k1u ** 2)) |
3074 | 164 | self.assertEqual(parts(q1 ** -2), (k1m ** -2, k1u ** -2)) | 167 | self.assertEqual(parts(q1 ** -2), (k1m ** -2, k1u ** -2)) |
3075 | @@ -177,8 +180,10 @@ | |||
3076 | 177 | self.assertQuantityAlmostEqual(v1.to_base_units(), v2) | 180 | self.assertQuantityAlmostEqual(v1.to_base_units(), v2) |
3077 | 178 | self.assertQuantityAlmostEqual(v1.to_base_units(), v2.to_base_units()) | 181 | self.assertQuantityAlmostEqual(v1.to_base_units(), v2.to_base_units()) |
3078 | 179 | 182 | ||
3079 | 183 | @unittest.expectedFailure | ||
3080 | 180 | def test_issue86c(self): | 184 | def test_issue86c(self): |
3081 | 181 | ureg = self.ureg | 185 | ureg = self.ureg |
3082 | 186 | ureg.autoconvert_offset_to_baseunit = True | ||
3083 | 182 | T = ureg.degC | 187 | T = ureg.degC |
3084 | 183 | T = 100. * T | 188 | T = 100. * T |
3085 | 184 | self.assertQuantityAlmostEqual(ureg.k*2*T, ureg.k*(2*T)) | 189 | self.assertQuantityAlmostEqual(ureg.k*2*T, ureg.k*(2*T)) |
3086 | 185 | 190 | ||
3087 | === modified file 'pint/testsuite/test_numpy.py' | |||
3088 | --- pint/testsuite/test_numpy.py 2014-09-05 23:26:05 +0000 | |||
3089 | +++ pint/testsuite/test_numpy.py 2015-01-07 15:51:38 +0000 | |||
3090 | @@ -2,8 +2,13 @@ | |||
3091 | 2 | 2 | ||
3092 | 3 | from __future__ import division, unicode_literals, print_function, absolute_import | 3 | from __future__ import division, unicode_literals, print_function, absolute_import |
3093 | 4 | 4 | ||
3094 | 5 | import copy | ||
3095 | 6 | import operator as op | ||
3096 | 7 | |||
3097 | 8 | from pint import DimensionalityError | ||
3098 | 5 | from pint.compat import np, unittest | 9 | from pint.compat import np, unittest |
3099 | 6 | from pint.testsuite import QuantityTestCase, helpers | 10 | from pint.testsuite import QuantityTestCase, helpers |
3100 | 11 | from pint.testsuite.test_umath import TestUFuncs | ||
3101 | 7 | 12 | ||
3102 | 8 | 13 | ||
3103 | 9 | @helpers.requires_numpy() | 14 | @helpers.requires_numpy() |
3104 | @@ -189,9 +194,11 @@ | |||
3105 | 189 | q[0] = 1*self.ureg.m | 194 | q[0] = 1*self.ureg.m |
3106 | 190 | self.assertQuantityEqual(q, [[1,1],[3,4]]*self.ureg.m) | 195 | self.assertQuantityEqual(q, [[1,1],[3,4]]*self.ureg.m) |
3107 | 191 | 196 | ||
3110 | 192 | q[0] = (1,2)*self.ureg.m | 197 | q = self.q.copy() |
3111 | 193 | self.assertQuantityEqual(q, self.q) | 198 | q.__setitem__(Ellipsis, 1*self.ureg.m) |
3112 | 199 | self.assertQuantityEqual(q, [[1,1],[1,1]]*self.ureg.m) | ||
3113 | 194 | 200 | ||
3114 | 201 | q = self.q.copy() | ||
3115 | 195 | q[:] = 1*self.ureg.m | 202 | q[:] = 1*self.ureg.m |
3116 | 196 | self.assertQuantityEqual(q, [[1,1],[1,1]]*self.ureg.m) | 203 | self.assertQuantityEqual(q, [[1,1],[1,1]]*self.ureg.m) |
3117 | 197 | 204 | ||
3118 | @@ -239,58 +246,68 @@ | |||
3119 | 239 | self.assertQuantityEqual(u == 1, u.magnitude == 1) | 246 | self.assertQuantityEqual(u == 1, u.magnitude == 1) |
3120 | 240 | 247 | ||
3121 | 241 | 248 | ||
3125 | 242 | from pint.testsuite.test_umath import TestUFuncs | 249 | @helpers.requires_numpy() |
3126 | 243 | @unittest.skip | 250 | class TestNumpyNeedsSubclassing(TestUFuncs): |
3124 | 244 | class TestNumpyNotSupported(TestUFuncs): | ||
3127 | 245 | 251 | ||
3128 | 246 | FORCE_NDARRAY = True | 252 | FORCE_NDARRAY = True |
3129 | 247 | 253 | ||
3130 | 254 | @property | ||
3131 | 255 | def q(self): | ||
3132 | 256 | return [1. ,2., 3., 4.] * self.ureg.J | ||
3133 | 248 | 257 | ||
3134 | 258 | @unittest.expectedFailure | ||
3135 | 249 | def test_unwrap(self): | 259 | def test_unwrap(self): |
3136 | 250 | """unwrap depends on diff | 260 | """unwrap depends on diff |
3137 | 251 | """ | 261 | """ |
3140 | 252 | self.assertEqual(np.unwrap([0,3*np.pi]*self.ureg.radians), [0,np.pi]) | 262 | self.assertQuantityEqual(np.unwrap([0,3*np.pi]*self.ureg.radians), [0,np.pi]) |
3141 | 253 | self.assertEqual(np.unwrap([0,540]*self.ureg.deg), [0,180]*self.ureg.deg) | 263 | self.assertQuantityEqual(np.unwrap([0,540]*self.ureg.deg), [0,180]*self.ureg.deg) |
3142 | 254 | 264 | ||
3143 | 265 | @unittest.expectedFailure | ||
3144 | 255 | def test_trapz(self): | 266 | def test_trapz(self): |
3145 | 256 | """Units are erased by asanyarray, Quantity does not inherit from NDArray | 267 | """Units are erased by asanyarray, Quantity does not inherit from NDArray |
3146 | 257 | """ | 268 | """ |
3148 | 258 | self.assertEqual(np.trapz(self.q, dx = 1*self.ureg.m), 7.5 * self.ureg.J*self.ureg.m) | 269 | self.assertQuantityEqual(np.trapz(self.q, dx=1*self.ureg.m), 7.5 * self.ureg.J*self.ureg.m) |
3149 | 259 | 270 | ||
3150 | 271 | @unittest.expectedFailure | ||
3151 | 260 | def test_diff(self): | 272 | def test_diff(self): |
3152 | 261 | """Units are erased by asanyarray, Quantity does not inherit from NDArray | 273 | """Units are erased by asanyarray, Quantity does not inherit from NDArray |
3153 | 262 | """ | 274 | """ |
3154 | 263 | self.assertQuantityEqual(np.diff(self.q, 1), [1, 1, 1] * self.ureg.J) | 275 | self.assertQuantityEqual(np.diff(self.q, 1), [1, 1, 1] * self.ureg.J) |
3155 | 264 | 276 | ||
3156 | 277 | @unittest.expectedFailure | ||
3157 | 265 | def test_ediff1d(self): | 278 | def test_ediff1d(self): |
3158 | 266 | """Units are erased by asanyarray, Quantity does not inherit from NDArray | 279 | """Units are erased by asanyarray, Quantity does not inherit from NDArray |
3159 | 267 | """ | 280 | """ |
3161 | 268 | self.assertEqual(np.ediff1d(self.q, 1), [1, 1, 1] * self.ureg.J) | 281 | self.assertQuantityEqual(np.ediff1d(self.q, 1 * self.ureg.J), [1, 1, 1] * self.ureg.J) |
3162 | 269 | 282 | ||
3163 | 283 | @unittest.expectedFailure | ||
3164 | 270 | def test_fix(self): | 284 | def test_fix(self): |
3165 | 271 | """Units are erased by asanyarray, Quantity does not inherit from NDArray | 285 | """Units are erased by asanyarray, Quantity does not inherit from NDArray |
3166 | 272 | """ | 286 | """ |
3169 | 273 | self.assertEqual(np.fix(3.14 * self.ureg.m), 3.0 * self.ureg.m) | 287 | self.assertQuantityEqual(np.fix(3.14 * self.ureg.m), 3.0 * self.ureg.m) |
3170 | 274 | self.assertEqual(np.fix(3.0 * self.ureg.m), 3.0 * self.ureg.m) | 288 | self.assertQuantityEqual(np.fix(3.0 * self.ureg.m), 3.0 * self.ureg.m) |
3171 | 275 | self.assertQuantityEqual( | 289 | self.assertQuantityEqual( |
3172 | 276 | np.fix([2.1, 2.9, -2.1, -2.9] * self.ureg.m), | 290 | np.fix([2.1, 2.9, -2.1, -2.9] * self.ureg.m), |
3173 | 277 | [2., 2., -2., -2.] * self.ureg.m | 291 | [2., 2., -2., -2.] * self.ureg.m |
3174 | 278 | ) | 292 | ) |
3175 | 279 | 293 | ||
3176 | 294 | @unittest.expectedFailure | ||
3177 | 280 | def test_gradient(self): | 295 | def test_gradient(self): |
3178 | 281 | """shape is a property not a function | 296 | """shape is a property not a function |
3179 | 282 | """ | 297 | """ |
3180 | 283 | l = np.gradient([[1,1],[3,4]] * self.ureg.J, 1 * self.ureg.m) | 298 | l = np.gradient([[1,1],[3,4]] * self.ureg.J, 1 * self.ureg.m) |
3183 | 284 | self.assertEqual(l[0], [[2., 3.], [2., 3.]] * self.ureg.J / self.ureg.m) | 299 | self.assertQuantityEqual(l[0], [[2., 3.], [2., 3.]] * self.ureg.J / self.ureg.m) |
3184 | 285 | self.assertEqual(l[1], [[0., 0.], [1., 1.]] * self.ureg.J / self.ureg.m) | 300 | self.assertQuantityEqual(l[1], [[0., 0.], [1., 1.]] * self.ureg.J / self.ureg.m) |
3185 | 286 | 301 | ||
3186 | 302 | @unittest.expectedFailure | ||
3187 | 287 | def test_cross(self): | 303 | def test_cross(self): |
3188 | 288 | """Units are erased by asarray, Quantity does not inherit from NDArray | 304 | """Units are erased by asarray, Quantity does not inherit from NDArray |
3189 | 289 | """ | 305 | """ |
3193 | 290 | a = [3,-3, 1] * self.ureg.kPa | 306 | a = [[3,-3, 1]] * self.ureg.kPa |
3194 | 291 | b = [4, 9, 2] * self.ureg.m**2 | 307 | b = [[4, 9, 2]] * self.ureg.m**2 |
3195 | 292 | self.assertQuantityEqual(np.cross(a,b), [-15,-2,39]*self.ureg.kPa*self.ureg.m**2) | 308 | self.assertQuantityEqual(np.cross(a, b), [-15, -2, 39] * self.ureg.kPa * self.ureg.m**2) |
3196 | 293 | 309 | ||
3197 | 310 | @unittest.expectedFailure | ||
3198 | 294 | def test_power(self): | 311 | def test_power(self): |
3199 | 295 | """This is not supported as different elements might end up with different units | 312 | """This is not supported as different elements might end up with different units |
3200 | 296 | 313 | ||
3201 | @@ -302,6 +319,7 @@ | |||
3202 | 302 | (self.qless, np.asarray([1., 2, 3, 4])), | 319 | (self.qless, np.asarray([1., 2, 3, 4])), |
3203 | 303 | (self.q2, ),) | 320 | (self.q2, ),) |
3204 | 304 | 321 | ||
3205 | 322 | @unittest.expectedFailure | ||
3206 | 305 | def test_ones_like(self): | 323 | def test_ones_like(self): |
3207 | 306 | """Units are erased by emptyarra, Quantity does not inherit from NDArray | 324 | """Units are erased by emptyarra, Quantity does not inherit from NDArray |
3208 | 307 | """ | 325 | """ |
3209 | @@ -385,3 +403,39 @@ | |||
3210 | 385 | (self.qless, 2), | 403 | (self.qless, 2), |
3211 | 386 | (self.q1, self.q2, self.qs, ), | 404 | (self.q1, self.q2, self.qs, ), |
3212 | 387 | 'same') | 405 | 'same') |
3213 | 406 | |||
3214 | 407 | |||
3215 | 408 | class TestNDArrayQunatityMath(QuantityTestCase): | ||
3216 | 409 | |||
3217 | 410 | @helpers.requires_numpy() | ||
3218 | 411 | def test_exponentiation_array_exp(self): | ||
3219 | 412 | arr = np.array(range(3), dtype=np.float) | ||
3220 | 413 | q = self.Q_(arr, None) | ||
3221 | 414 | |||
3222 | 415 | for op_ in [op.pow, op.ipow]: | ||
3223 | 416 | q_cp = copy.copy(q) | ||
3224 | 417 | self.assertRaises(DimensionalityError, op_, 2., q_cp) | ||
3225 | 418 | arr_cp = copy.copy(arr) | ||
3226 | 419 | arr_cp = copy.copy(arr) | ||
3227 | 420 | q_cp = copy.copy(q) | ||
3228 | 421 | self.assertRaises(DimensionalityError, op_, q_cp, arr_cp) | ||
3229 | 422 | q_cp = copy.copy(q) | ||
3230 | 423 | q2_cp = copy.copy(q) | ||
3231 | 424 | self.assertRaises(DimensionalityError, op_, q_cp, q2_cp) | ||
3232 | 425 | |||
3233 | 426 | @unittest.expectedFailure | ||
3234 | 427 | @helpers.requires_numpy() | ||
3235 | 428 | def test_exponentiation_array_exp_2(self): | ||
3236 | 429 | arr = np.array(range(3), dtype=np.float) | ||
3237 | 430 | #q = self.Q_(copy.copy(arr), None) | ||
3238 | 431 | q = self.Q_(copy.copy(arr), 'meter') | ||
3239 | 432 | arr_cp = copy.copy(arr) | ||
3240 | 433 | q_cp = copy.copy(q) | ||
3241 | 434 | # this fails as expected since numpy 1.8.0 but... | ||
3242 | 435 | self.assertRaises(DimensionalityError, op.pow, arr_cp, q_cp) | ||
3243 | 436 | # ..not for op.ipow ! | ||
3244 | 437 | # q_cp is treated as if it is an array. The units are ignored. | ||
3245 | 438 | # _Quantity.__ipow__ is never called | ||
3246 | 439 | arr_cp = copy.copy(arr) | ||
3247 | 440 | q_cp = copy.copy(q) | ||
3248 | 441 | self.assertRaises(DimensionalityError, op.ipow, arr_cp, q_cp) | ||
3249 | 388 | 442 | ||
3250 | === modified file 'pint/testsuite/test_quantity.py' | |||
3251 | --- pint/testsuite/test_quantity.py 2014-09-05 23:26:05 +0000 | |||
3252 | +++ pint/testsuite/test_quantity.py 2015-01-07 15:51:38 +0000 | |||
3253 | @@ -6,10 +6,11 @@ | |||
3254 | 6 | import math | 6 | import math |
3255 | 7 | import operator as op | 7 | import operator as op |
3256 | 8 | 8 | ||
3258 | 9 | from pint import DimensionalityError, UnitRegistry | 9 | from pint import DimensionalityError, OffsetUnitCalculusError, UnitRegistry |
3259 | 10 | from pint.unit import UnitsContainer | 10 | from pint.unit import UnitsContainer |
3261 | 11 | from pint.compat import string_types, PYTHON3, np | 11 | from pint.compat import string_types, PYTHON3, np, unittest |
3262 | 12 | from pint.testsuite import QuantityTestCase, helpers | 12 | from pint.testsuite import QuantityTestCase, helpers |
3263 | 13 | from pint.testsuite.parameterized import ParameterizedTestCase | ||
3264 | 13 | 14 | ||
3265 | 14 | 15 | ||
3266 | 15 | class TestQuantity(QuantityTestCase): | 16 | class TestQuantity(QuantityTestCase): |
3267 | @@ -149,7 +150,7 @@ | |||
3268 | 149 | # Conversions with single units take a different codepath than | 150 | # Conversions with single units take a different codepath than |
3269 | 150 | # Conversions with more than one unit. | 151 | # Conversions with more than one unit. |
3270 | 151 | src_dst1 = UnitsContainer(meter=1), UnitsContainer(inch=1) | 152 | src_dst1 = UnitsContainer(meter=1), UnitsContainer(inch=1) |
3272 | 152 | src_dst2 = UnitsContainer(meter=1, seconds=-1), UnitsContainer(inch=1, minutes=-1) | 153 | src_dst2 = UnitsContainer(meter=1, second=-1), UnitsContainer(inch=1, minute=-1) |
3273 | 153 | for src, dst in (src_dst1, src_dst2): | 154 | for src, dst in (src_dst1, src_dst2): |
3274 | 154 | a = np.ones((3, 1)) | 155 | a = np.ones((3, 1)) |
3275 | 155 | ac = np.ones((3, 1)) | 156 | ac = np.ones((3, 1)) |
3276 | @@ -209,14 +210,12 @@ | |||
3277 | 209 | 210 | ||
3278 | 210 | 211 | ||
3279 | 211 | def test_offset_delta(self): | 212 | def test_offset_delta(self): |
3283 | 212 | self.assertQuantityAlmostEqual(self.Q_(0, 'delta_kelvin').to('delta_kelvin'), self.Q_(0, 'delta_kelvin')) | 213 | self.assertQuantityAlmostEqual(self.Q_(0, 'delta_degC').to('kelvin'), self.Q_(0, 'kelvin')) |
3284 | 213 | self.assertQuantityAlmostEqual(self.Q_(0, 'delta_degC').to('delta_kelvin'), self.Q_(0, 'delta_kelvin')) | 214 | self.assertQuantityAlmostEqual(self.Q_(0, 'delta_degF').to('kelvin'), self.Q_(0, 'kelvin'), rtol=0.01) |
3282 | 214 | self.assertQuantityAlmostEqual(self.Q_(0, 'delta_degF').to('delta_kelvin'), self.Q_(0, 'delta_kelvin'), rtol=0.01) | ||
3285 | 215 | 215 | ||
3290 | 216 | self.assertQuantityAlmostEqual(self.Q_(100, 'delta_kelvin').to('delta_kelvin'), self.Q_(100, 'delta_kelvin')) | 216 | self.assertQuantityAlmostEqual(self.Q_(100, 'kelvin').to('delta_degC'), self.Q_(100, 'delta_degC')) |
3291 | 217 | self.assertQuantityAlmostEqual(self.Q_(100, 'delta_kelvin').to('delta_degC'), self.Q_(100, 'delta_degC')) | 217 | self.assertQuantityAlmostEqual(self.Q_(100, 'kelvin').to('delta_degF'), self.Q_(180, 'delta_degF'), rtol=0.01) |
3292 | 218 | self.assertQuantityAlmostEqual(self.Q_(100, 'delta_kelvin').to('delta_degF'), self.Q_(180, 'delta_degF'), rtol=0.01) | 218 | self.assertQuantityAlmostEqual(self.Q_(100, 'delta_degF').to('kelvin'), self.Q_(55.55555556, 'kelvin'), rtol=0.01) |
3289 | 219 | self.assertQuantityAlmostEqual(self.Q_(100, 'delta_degF').to('delta_kelvin'), self.Q_(55.55555556, 'delta_kelvin'), rtol=0.01) | ||
3293 | 220 | self.assertQuantityAlmostEqual(self.Q_(100, 'delta_degC').to('delta_degF'), self.Q_(180, 'delta_degF'), rtol=0.01) | 219 | self.assertQuantityAlmostEqual(self.Q_(100, 'delta_degC').to('delta_degF'), self.Q_(180, 'delta_degF'), rtol=0.01) |
3294 | 221 | self.assertQuantityAlmostEqual(self.Q_(100, 'delta_degF').to('delta_degC'), self.Q_(55.55555556, 'delta_degC'), rtol=0.01) | 220 | self.assertQuantityAlmostEqual(self.Q_(100, 'delta_degF').to('delta_degC'), self.Q_(55.55555556, 'delta_degC'), rtol=0.01) |
3295 | 222 | 221 | ||
3296 | @@ -450,3 +449,547 @@ | |||
3297 | 450 | from pint import _DEFAULT_REGISTRY | 449 | from pint import _DEFAULT_REGISTRY |
3298 | 451 | cls.ureg = _DEFAULT_REGISTRY | 450 | cls.ureg = _DEFAULT_REGISTRY |
3299 | 452 | cls.Q_ = cls.ureg.Quantity | 451 | cls.Q_ = cls.ureg.Quantity |
3300 | 452 | |||
3301 | 453 | |||
3302 | 454 | class TestOffsetUnitMath(QuantityTestCase, ParameterizedTestCase): | ||
3303 | 455 | |||
3304 | 456 | def setup(self): | ||
3305 | 457 | self.ureg.autoconvert_offset_to_baseunit = False | ||
3306 | 458 | self.ureg.default_as_delta = True | ||
3307 | 459 | |||
3308 | 460 | additions = [ | ||
3309 | 461 | # --- input tuple -------------------- | -- expected result -- | ||
3310 | 462 | (((100, 'kelvin'), (10, 'kelvin')), (110, 'kelvin')), | ||
3311 | 463 | (((100, 'kelvin'), (10, 'degC')), 'error'), | ||
3312 | 464 | (((100, 'kelvin'), (10, 'degF')), 'error'), | ||
3313 | 465 | (((100, 'kelvin'), (10, 'degR')), (105.56, 'kelvin')), | ||
3314 | 466 | (((100, 'kelvin'), (10, 'delta_degC')), (110, 'kelvin')), | ||
3315 | 467 | (((100, 'kelvin'), (10, 'delta_degF')), (105.56, 'kelvin')), | ||
3316 | 468 | |||
3317 | 469 | (((100, 'degC'), (10, 'kelvin')), 'error'), | ||
3318 | 470 | (((100, 'degC'), (10, 'degC')), 'error'), | ||
3319 | 471 | (((100, 'degC'), (10, 'degF')), 'error'), | ||
3320 | 472 | (((100, 'degC'), (10, 'degR')), 'error'), | ||
3321 | 473 | (((100, 'degC'), (10, 'delta_degC')), (110, 'degC')), | ||
3322 | 474 | (((100, 'degC'), (10, 'delta_degF')), (105.56, 'degC')), | ||
3323 | 475 | |||
3324 | 476 | (((100, 'degF'), (10, 'kelvin')), 'error'), | ||
3325 | 477 | (((100, 'degF'), (10, 'degC')), 'error'), | ||
3326 | 478 | (((100, 'degF'), (10, 'degF')), 'error'), | ||
3327 | 479 | (((100, 'degF'), (10, 'degR')), 'error'), | ||
3328 | 480 | (((100, 'degF'), (10, 'delta_degC')), (118, 'degF')), | ||
3329 | 481 | (((100, 'degF'), (10, 'delta_degF')), (110, 'degF')), | ||
3330 | 482 | |||
3331 | 483 | (((100, 'degR'), (10, 'kelvin')), (118, 'degR')), | ||
3332 | 484 | (((100, 'degR'), (10, 'degC')), 'error'), | ||
3333 | 485 | (((100, 'degR'), (10, 'degF')), 'error'), | ||
3334 | 486 | (((100, 'degR'), (10, 'degR')), (110, 'degR')), | ||
3335 | 487 | (((100, 'degR'), (10, 'delta_degC')), (118, 'degR')), | ||
3336 | 488 | (((100, 'degR'), (10, 'delta_degF')), (110, 'degR')), | ||
3337 | 489 | |||
3338 | 490 | (((100, 'delta_degC'), (10, 'kelvin')), (110, 'kelvin')), | ||
3339 | 491 | (((100, 'delta_degC'), (10, 'degC')), (110, 'degC')), | ||
3340 | 492 | (((100, 'delta_degC'), (10, 'degF')), (190, 'degF')), | ||
3341 | 493 | (((100, 'delta_degC'), (10, 'degR')), (190, 'degR')), | ||
3342 | 494 | (((100, 'delta_degC'), (10, 'delta_degC')), (110, 'delta_degC')), | ||
3343 | 495 | (((100, 'delta_degC'), (10, 'delta_degF')), (105.56, 'delta_degC')), | ||
3344 | 496 | |||
3345 | 497 | (((100, 'delta_degF'), (10, 'kelvin')), (65.56, 'kelvin')), | ||
3346 | 498 | (((100, 'delta_degF'), (10, 'degC')), (65.56, 'degC')), | ||
3347 | 499 | (((100, 'delta_degF'), (10, 'degF')), (110, 'degF')), | ||
3348 | 500 | (((100, 'delta_degF'), (10, 'degR')), (110, 'degR')), | ||
3349 | 501 | (((100, 'delta_degF'), (10, 'delta_degC')), (118, 'delta_degF')), | ||
3350 | 502 | (((100, 'delta_degF'), (10, 'delta_degF')), (110, 'delta_degF')), | ||
3351 | 503 | ] | ||
3352 | 504 | |||
3353 | 505 | @ParameterizedTestCase.parameterize(("input", "expected_output"), | ||
3354 | 506 | additions) | ||
3355 | 507 | def test_addition(self, input_tuple, expected): | ||
3356 | 508 | self.ureg.autoconvert_offset_to_baseunit = False | ||
3357 | 509 | qin1, qin2 = input_tuple | ||
3358 | 510 | q1, q2 = self.Q_(*qin1), self.Q_(*qin2) | ||
3359 | 511 | # update input tuple with new values to have correct values on failure | ||
3360 | 512 | input_tuple = q1, q2 | ||
3361 | 513 | if expected == 'error': | ||
3362 | 514 | self.assertRaises(OffsetUnitCalculusError, op.add, q1, q2) | ||
3363 | 515 | else: | ||
3364 | 516 | expected = self.Q_(*expected) | ||
3365 | 517 | self.assertEqual(op.add(q1, q2).units, expected.units) | ||
3366 | 518 | self.assertQuantityAlmostEqual(op.add(q1, q2), expected, | ||
3367 | 519 | atol=0.01) | ||
3368 | 520 | |||
3369 | 521 | @helpers.requires_numpy() | ||
3370 | 522 | @ParameterizedTestCase.parameterize(("input", "expected_output"), | ||
3371 | 523 | additions) | ||
3372 | 524 | def test_inplace_addition(self, input_tuple, expected): | ||
3373 | 525 | self.ureg.autoconvert_offset_to_baseunit = False | ||
3374 | 526 | (q1v, q1u), (q2v, q2u) = input_tuple | ||
3375 | 527 | # update input tuple with new values to have correct values on failure | ||
3376 | 528 | input_tuple = ((np.array([q1v]*2, dtype=np.float), q1u), | ||
3377 | 529 | (np.array([q2v]*2, dtype=np.float), q2u)) | ||
3378 | 530 | Q_ = self.Q_ | ||
3379 | 531 | qin1, qin2 = input_tuple | ||
3380 | 532 | q1, q2 = Q_(*qin1), Q_(*qin2) | ||
3381 | 533 | q1_cp = copy.copy(q1) | ||
3382 | 534 | if expected == 'error': | ||
3383 | 535 | self.assertRaises(OffsetUnitCalculusError, op.iadd, q1_cp, q2) | ||
3384 | 536 | else: | ||
3385 | 537 | expected = np.array([expected[0]]*2, dtype=np.float), expected[1] | ||
3386 | 538 | self.assertEqual(op.iadd(q1_cp, q2).units, Q_(*expected).units) | ||
3387 | 539 | q1_cp = copy.copy(q1) | ||
3388 | 540 | self.assertQuantityAlmostEqual(op.iadd(q1_cp, q2), Q_(*expected), | ||
3389 | 541 | atol=0.01) | ||
3390 | 542 | |||
3391 | 543 | subtractions = [ | ||
3392 | 544 | (((100, 'kelvin'), (10, 'kelvin')), (90, 'kelvin')), | ||
3393 | 545 | (((100, 'kelvin'), (10, 'degC')), (-183.15, 'kelvin')), | ||
3394 | 546 | (((100, 'kelvin'), (10, 'degF')), (-160.93, 'kelvin')), | ||
3395 | 547 | (((100, 'kelvin'), (10, 'degR')), (94.44, 'kelvin')), | ||
3396 | 548 | (((100, 'kelvin'), (10, 'delta_degC')), (90, 'kelvin')), | ||
3397 | 549 | (((100, 'kelvin'), (10, 'delta_degF')), (94.44, 'kelvin')), | ||
3398 | 550 | |||
3399 | 551 | (((100, 'degC'), (10, 'kelvin')), (363.15, 'delta_degC')), | ||
3400 | 552 | (((100, 'degC'), (10, 'degC')), (90, 'delta_degC')), | ||
3401 | 553 | (((100, 'degC'), (10, 'degF')), (112.22, 'delta_degC')), | ||
3402 | 554 | (((100, 'degC'), (10, 'degR')), (367.59, 'delta_degC')), | ||
3403 | 555 | (((100, 'degC'), (10, 'delta_degC')), (90, 'degC')), | ||
3404 | 556 | (((100, 'degC'), (10, 'delta_degF')), (94.44, 'degC')), | ||
3405 | 557 | |||
3406 | 558 | (((100, 'degF'), (10, 'kelvin')), (541.67, 'delta_degF')), | ||
3407 | 559 | (((100, 'degF'), (10, 'degC')), (50, 'delta_degF')), | ||
3408 | 560 | (((100, 'degF'), (10, 'degF')), (90, 'delta_degF')), | ||
3409 | 561 | (((100, 'degF'), (10, 'degR')), (549.67, 'delta_degF')), | ||
3410 | 562 | (((100, 'degF'), (10, 'delta_degC')), (82, 'degF')), | ||
3411 | 563 | (((100, 'degF'), (10, 'delta_degF')), (90, 'degF')), | ||
3412 | 564 | |||
3413 | 565 | (((100, 'degR'), (10, 'kelvin')), (82, 'degR')), | ||
3414 | 566 | (((100, 'degR'), (10, 'degC')), (-409.67, 'degR')), | ||
3415 | 567 | (((100, 'degR'), (10, 'degF')), (-369.67, 'degR')), | ||
3416 | 568 | (((100, 'degR'), (10, 'degR')), (90, 'degR')), | ||
3417 | 569 | (((100, 'degR'), (10, 'delta_degC')), (82, 'degR')), | ||
3418 | 570 | (((100, 'degR'), (10, 'delta_degF')), (90, 'degR')), | ||
3419 | 571 | |||
3420 | 572 | (((100, 'delta_degC'), (10, 'kelvin')), (90, 'kelvin')), | ||
3421 | 573 | (((100, 'delta_degC'), (10, 'degC')), (90, 'degC')), | ||
3422 | 574 | (((100, 'delta_degC'), (10, 'degF')), (170, 'degF')), | ||
3423 | 575 | (((100, 'delta_degC'), (10, 'degR')), (170, 'degR')), | ||
3424 | 576 | (((100, 'delta_degC'), (10, 'delta_degC')), (90, 'delta_degC')), | ||
3425 | 577 | (((100, 'delta_degC'), (10, 'delta_degF')), (94.44, 'delta_degC')), | ||
3426 | 578 | |||
3427 | 579 | (((100, 'delta_degF'), (10, 'kelvin')), (45.56, 'kelvin')), | ||
3428 | 580 | (((100, 'delta_degF'), (10, 'degC')), (45.56, 'degC')), | ||
3429 | 581 | (((100, 'delta_degF'), (10, 'degF')), (90, 'degF')), | ||
3430 | 582 | (((100, 'delta_degF'), (10, 'degR')), (90, 'degR')), | ||
3431 | 583 | (((100, 'delta_degF'), (10, 'delta_degC')), (82, 'delta_degF')), | ||
3432 | 584 | (((100, 'delta_degF'), (10, 'delta_degF')), (90, 'delta_degF')), | ||
3433 | 585 | ] | ||
3434 | 586 | |||
3435 | 587 | @ParameterizedTestCase.parameterize(("input", "expected_output"), | ||
3436 | 588 | subtractions) | ||
3437 | 589 | def test_subtraction(self, input_tuple, expected): | ||
3438 | 590 | self.ureg.autoconvert_offset_to_baseunit = False | ||
3439 | 591 | qin1, qin2 = input_tuple | ||
3440 | 592 | q1, q2 = self.Q_(*qin1), self.Q_(*qin2) | ||
3441 | 593 | input_tuple = q1, q2 | ||
3442 | 594 | if expected == 'error': | ||
3443 | 595 | self.assertRaises(OffsetUnitCalculusError, op.sub, q1, q2) | ||
3444 | 596 | else: | ||
3445 | 597 | expected = self.Q_(*expected) | ||
3446 | 598 | self.assertEqual(op.sub(q1, q2).units, expected.units) | ||
3447 | 599 | self.assertQuantityAlmostEqual(op.sub(q1, q2), expected, | ||
3448 | 600 | atol=0.01) | ||
3449 | 601 | |||
3450 | 602 | # @unittest.expectedFailure | ||
3451 | 603 | @helpers.requires_numpy() | ||
3452 | 604 | @ParameterizedTestCase.parameterize(("input", "expected_output"), | ||
3453 | 605 | subtractions) | ||
3454 | 606 | def test_inplace_subtraction(self, input_tuple, expected): | ||
3455 | 607 | self.ureg.autoconvert_offset_to_baseunit = False | ||
3456 | 608 | (q1v, q1u), (q2v, q2u) = input_tuple | ||
3457 | 609 | # update input tuple with new values to have correct values on failure | ||
3458 | 610 | input_tuple = ((np.array([q1v]*2, dtype=np.float), q1u), | ||
3459 | 611 | (np.array([q2v]*2, dtype=np.float), q2u)) | ||
3460 | 612 | Q_ = self.Q_ | ||
3461 | 613 | qin1, qin2 = input_tuple | ||
3462 | 614 | q1, q2 = Q_(*qin1), Q_(*qin2) | ||
3463 | 615 | q1_cp = copy.copy(q1) | ||
3464 | 616 | if expected == 'error': | ||
3465 | 617 | self.assertRaises(OffsetUnitCalculusError, op.isub, q1_cp, q2) | ||
3466 | 618 | else: | ||
3467 | 619 | expected = np.array([expected[0]]*2, dtype=np.float), expected[1] | ||
3468 | 620 | self.assertEqual(op.isub(q1_cp, q2).units, Q_(*expected).units) | ||
3469 | 621 | q1_cp = copy.copy(q1) | ||
3470 | 622 | self.assertQuantityAlmostEqual(op.isub(q1_cp, q2), Q_(*expected), | ||
3471 | 623 | atol=0.01) | ||
3472 | 624 | |||
3473 | 625 | multiplications = [ | ||
3474 | 626 | (((100, 'kelvin'), (10, 'kelvin')), (1000, 'kelvin**2')), | ||
3475 | 627 | (((100, 'kelvin'), (10, 'degC')), 'error'), | ||
3476 | 628 | (((100, 'kelvin'), (10, 'degF')), 'error'), | ||
3477 | 629 | (((100, 'kelvin'), (10, 'degR')), (1000, 'kelvin*degR')), | ||
3478 | 630 | (((100, 'kelvin'), (10, 'delta_degC')), (1000, 'kelvin*delta_degC')), | ||
3479 | 631 | (((100, 'kelvin'), (10, 'delta_degF')), (1000, 'kelvin*delta_degF')), | ||
3480 | 632 | |||
3481 | 633 | (((100, 'degC'), (10, 'kelvin')), 'error'), | ||
3482 | 634 | (((100, 'degC'), (10, 'degC')), 'error'), | ||
3483 | 635 | (((100, 'degC'), (10, 'degF')), 'error'), | ||
3484 | 636 | (((100, 'degC'), (10, 'degR')), 'error'), | ||
3485 | 637 | (((100, 'degC'), (10, 'delta_degC')), 'error'), | ||
3486 | 638 | (((100, 'degC'), (10, 'delta_degF')), 'error'), | ||
3487 | 639 | |||
3488 | 640 | (((100, 'degF'), (10, 'kelvin')), 'error'), | ||
3489 | 641 | (((100, 'degF'), (10, 'degC')), 'error'), | ||
3490 | 642 | (((100, 'degF'), (10, 'degF')), 'error'), | ||
3491 | 643 | (((100, 'degF'), (10, 'degR')), 'error'), | ||
3492 | 644 | (((100, 'degF'), (10, 'delta_degC')), 'error'), | ||
3493 | 645 | (((100, 'degF'), (10, 'delta_degF')), 'error'), | ||
3494 | 646 | |||
3495 | 647 | (((100, 'degR'), (10, 'kelvin')), (1000, 'degR*kelvin')), | ||
3496 | 648 | (((100, 'degR'), (10, 'degC')), 'error'), | ||
3497 | 649 | (((100, 'degR'), (10, 'degF')), 'error'), | ||
3498 | 650 | (((100, 'degR'), (10, 'degR')), (1000, 'degR**2')), | ||
3499 | 651 | (((100, 'degR'), (10, 'delta_degC')), (1000, 'degR*delta_degC')), | ||
3500 | 652 | (((100, 'degR'), (10, 'delta_degF')), (1000, 'degR*delta_degF')), | ||
3501 | 653 | |||
3502 | 654 | (((100, 'delta_degC'), (10, 'kelvin')), (1000, 'delta_degC*kelvin')), | ||
3503 | 655 | (((100, 'delta_degC'), (10, 'degC')), 'error'), | ||
3504 | 656 | (((100, 'delta_degC'), (10, 'degF')), 'error'), | ||
3505 | 657 | (((100, 'delta_degC'), (10, 'degR')), (1000, 'delta_degC*degR')), | ||
3506 | 658 | (((100, 'delta_degC'), (10, 'delta_degC')), (1000, 'delta_degC**2')), | ||
3507 | 659 | (((100, 'delta_degC'), (10, 'delta_degF')), (1000, 'delta_degC*delta_degF')), | ||
3508 | 660 | |||
3509 | 661 | (((100, 'delta_degF'), (10, 'kelvin')), (1000, 'delta_degF*kelvin')), | ||
3510 | 662 | (((100, 'delta_degF'), (10, 'degC')), 'error'), | ||
3511 | 663 | (((100, 'delta_degF'), (10, 'degF')), 'error'), | ||
3512 | 664 | (((100, 'delta_degF'), (10, 'degR')), (1000, 'delta_degF*degR')), | ||
3513 | 665 | (((100, 'delta_degF'), (10, 'delta_degC')), (1000, 'delta_degF*delta_degC')), | ||
3514 | 666 | (((100, 'delta_degF'), (10, 'delta_degF')), (1000, 'delta_degF**2')), | ||
3515 | 667 | ] | ||
3516 | 668 | |||
3517 | 669 | @ParameterizedTestCase.parameterize(("input", "expected_output"), | ||
3518 | 670 | multiplications) | ||
3519 | 671 | def test_multiplication(self, input_tuple, expected): | ||
3520 | 672 | self.ureg.autoconvert_offset_to_baseunit = False | ||
3521 | 673 | qin1, qin2 = input_tuple | ||
3522 | 674 | q1, q2 = self.Q_(*qin1), self.Q_(*qin2) | ||
3523 | 675 | input_tuple = q1, q2 | ||
3524 | 676 | if expected == 'error': | ||
3525 | 677 | self.assertRaises(OffsetUnitCalculusError, op.mul, q1, q2) | ||
3526 | 678 | else: | ||
3527 | 679 | expected = self.Q_(*expected) | ||
3528 | 680 | self.assertEqual(op.mul(q1, q2).units, expected.units) | ||
3529 | 681 | self.assertQuantityAlmostEqual(op.mul(q1, q2), expected, | ||
3530 | 682 | atol=0.01) | ||
3531 | 683 | |||
3532 | 684 | @helpers.requires_numpy() | ||
3533 | 685 | @ParameterizedTestCase.parameterize(("input", "expected_output"), | ||
3534 | 686 | multiplications) | ||
3535 | 687 | def test_inplace_multiplication(self, input_tuple, expected): | ||
3536 | 688 | self.ureg.autoconvert_offset_to_baseunit = False | ||
3537 | 689 | (q1v, q1u), (q2v, q2u) = input_tuple | ||
3538 | 690 | # update input tuple with new values to have correct values on failure | ||
3539 | 691 | input_tuple = ((np.array([q1v]*2, dtype=np.float), q1u), | ||
3540 | 692 | (np.array([q2v]*2, dtype=np.float), q2u)) | ||
3541 | 693 | Q_ = self.Q_ | ||
3542 | 694 | qin1, qin2 = input_tuple | ||
3543 | 695 | q1, q2 = Q_(*qin1), Q_(*qin2) | ||
3544 | 696 | q1_cp = copy.copy(q1) | ||
3545 | 697 | if expected == 'error': | ||
3546 | 698 | self.assertRaises(OffsetUnitCalculusError, op.imul, q1_cp, q2) | ||
3547 | 699 | else: | ||
3548 | 700 | expected = np.array([expected[0]]*2, dtype=np.float), expected[1] | ||
3549 | 701 | self.assertEqual(op.imul(q1_cp, q2).units, Q_(*expected).units) | ||
3550 | 702 | q1_cp = copy.copy(q1) | ||
3551 | 703 | self.assertQuantityAlmostEqual(op.imul(q1_cp, q2), Q_(*expected), | ||
3552 | 704 | atol=0.01) | ||
3553 | 705 | |||
3554 | 706 | divisions = [ | ||
3555 | 707 | (((100, 'kelvin'), (10, 'kelvin')), (10, '')), | ||
3556 | 708 | (((100, 'kelvin'), (10, 'degC')), 'error'), | ||
3557 | 709 | (((100, 'kelvin'), (10, 'degF')), 'error'), | ||
3558 | 710 | (((100, 'kelvin'), (10, 'degR')), (10, 'kelvin/degR')), | ||
3559 | 711 | (((100, 'kelvin'), (10, 'delta_degC')), (10, 'kelvin/delta_degC')), | ||
3560 | 712 | (((100, 'kelvin'), (10, 'delta_degF')), (10, 'kelvin/delta_degF')), | ||
3561 | 713 | |||
3562 | 714 | (((100, 'degC'), (10, 'kelvin')), 'error'), | ||
3563 | 715 | (((100, 'degC'), (10, 'degC')), 'error'), | ||
3564 | 716 | (((100, 'degC'), (10, 'degF')), 'error'), | ||
3565 | 717 | (((100, 'degC'), (10, 'degR')), 'error'), | ||
3566 | 718 | (((100, 'degC'), (10, 'delta_degC')), 'error'), | ||
3567 | 719 | (((100, 'degC'), (10, 'delta_degF')), 'error'), | ||
3568 | 720 | |||
3569 | 721 | (((100, 'degF'), (10, 'kelvin')), 'error'), | ||
3570 | 722 | (((100, 'degF'), (10, 'degC')), 'error'), | ||
3571 | 723 | (((100, 'degF'), (10, 'degF')), 'error'), | ||
3572 | 724 | (((100, 'degF'), (10, 'degR')), 'error'), | ||
3573 | 725 | (((100, 'degF'), (10, 'delta_degC')), 'error'), | ||
3574 | 726 | (((100, 'degF'), (10, 'delta_degF')), 'error'), | ||
3575 | 727 | |||
3576 | 728 | (((100, 'degR'), (10, 'kelvin')), (10, 'degR/kelvin')), | ||
3577 | 729 | (((100, 'degR'), (10, 'degC')), 'error'), | ||
3578 | 730 | (((100, 'degR'), (10, 'degF')), 'error'), | ||
3579 | 731 | (((100, 'degR'), (10, 'degR')), (10, '')), | ||
3580 | 732 | (((100, 'degR'), (10, 'delta_degC')), (10, 'degR/delta_degC')), | ||
3581 | 733 | (((100, 'degR'), (10, 'delta_degF')), (10, 'degR/delta_degF')), | ||
3582 | 734 | |||
3583 | 735 | (((100, 'delta_degC'), (10, 'kelvin')), (10, 'delta_degC/kelvin')), | ||
3584 | 736 | (((100, 'delta_degC'), (10, 'degC')), 'error'), | ||
3585 | 737 | (((100, 'delta_degC'), (10, 'degF')), 'error'), | ||
3586 | 738 | (((100, 'delta_degC'), (10, 'degR')), (10, 'delta_degC/degR')), | ||
3587 | 739 | (((100, 'delta_degC'), (10, 'delta_degC')), (10, '')), | ||
3588 | 740 | (((100, 'delta_degC'), (10, 'delta_degF')), (10, 'delta_degC/delta_degF')), | ||
3589 | 741 | |||
3590 | 742 | (((100, 'delta_degF'), (10, 'kelvin')), (10, 'delta_degF/kelvin')), | ||
3591 | 743 | (((100, 'delta_degF'), (10, 'degC')), 'error'), | ||
3592 | 744 | (((100, 'delta_degF'), (10, 'degF')), 'error'), | ||
3593 | 745 | (((100, 'delta_degF'), (10, 'degR')), (10, 'delta_degF/degR')), | ||
3594 | 746 | (((100, 'delta_degF'), (10, 'delta_degC')), (10, 'delta_degF/delta_degC')), | ||
3595 | 747 | (((100, 'delta_degF'), (10, 'delta_degF')), (10, '')), | ||
3596 | 748 | ] | ||
3597 | 749 | |||
3598 | 750 | @ParameterizedTestCase.parameterize(("input", "expected_output"), | ||
3599 | 751 | divisions) | ||
3600 | 752 | def test_truedivision(self, input_tuple, expected): | ||
3601 | 753 | self.ureg.autoconvert_offset_to_baseunit = False | ||
3602 | 754 | qin1, qin2 = input_tuple | ||
3603 | 755 | q1, q2 = self.Q_(*qin1), self.Q_(*qin2) | ||
3604 | 756 | input_tuple = q1, q2 | ||
3605 | 757 | if expected == 'error': | ||
3606 | 758 | self.assertRaises(OffsetUnitCalculusError, op.truediv, q1, q2) | ||
3607 | 759 | else: | ||
3608 | 760 | expected = self.Q_(*expected) | ||
3609 | 761 | self.assertEqual(op.truediv(q1, q2).units, expected.units) | ||
3610 | 762 | self.assertQuantityAlmostEqual(op.truediv(q1, q2), expected, | ||
3611 | 763 | atol=0.01) | ||
3612 | 764 | |||
3613 | 765 | @helpers.requires_numpy() | ||
3614 | 766 | @ParameterizedTestCase.parameterize(("input", "expected_output"), | ||
3615 | 767 | divisions) | ||
3616 | 768 | def test_inplace_truedivision(self, input_tuple, expected): | ||
3617 | 769 | self.ureg.autoconvert_offset_to_baseunit = False | ||
3618 | 770 | (q1v, q1u), (q2v, q2u) = input_tuple | ||
3619 | 771 | # update input tuple with new values to have correct values on failure | ||
3620 | 772 | input_tuple = ((np.array([q1v]*2, dtype=np.float), q1u), | ||
3621 | 773 | (np.array([q2v]*2, dtype=np.float), q2u)) | ||
3622 | 774 | Q_ = self.Q_ | ||
3623 | 775 | qin1, qin2 = input_tuple | ||
3624 | 776 | q1, q2 = Q_(*qin1), Q_(*qin2) | ||
3625 | 777 | q1_cp = copy.copy(q1) | ||
3626 | 778 | if expected == 'error': | ||
3627 | 779 | self.assertRaises(OffsetUnitCalculusError, op.itruediv, q1_cp, q2) | ||
3628 | 780 | else: | ||
3629 | 781 | expected = np.array([expected[0]]*2, dtype=np.float), expected[1] | ||
3630 | 782 | self.assertEqual(op.itruediv(q1_cp, q2).units, Q_(*expected).units) | ||
3631 | 783 | q1_cp = copy.copy(q1) | ||
3632 | 784 | self.assertQuantityAlmostEqual(op.itruediv(q1_cp, q2), | ||
3633 | 785 | Q_(*expected), atol=0.01) | ||
3634 | 786 | |||
3635 | 787 | multiplications_with_autoconvert_to_baseunit = [ | ||
3636 | 788 | (((100, 'kelvin'), (10, 'degC')), (28315., 'kelvin**2')), | ||
3637 | 789 | (((100, 'kelvin'), (10, 'degF')), (26092.78, 'kelvin**2')), | ||
3638 | 790 | |||
3639 | 791 | (((100, 'degC'), (10, 'kelvin')), (3731.5, 'kelvin**2')), | ||
3640 | 792 | (((100, 'degC'), (10, 'degC')), (105657.42, 'kelvin**2')), | ||
3641 | 793 | (((100, 'degC'), (10, 'degF')), (97365.20, 'kelvin**2')), | ||
3642 | 794 | (((100, 'degC'), (10, 'degR')), (3731.5, 'kelvin*degR')), | ||
3643 | 795 | (((100, 'degC'), (10, 'delta_degC')), (3731.5, 'kelvin*delta_degC')), | ||
3644 | 796 | (((100, 'degC'), (10, 'delta_degF')), (3731.5, 'kelvin*delta_degF')), | ||
3645 | 797 | |||
3646 | 798 | (((100, 'degF'), (10, 'kelvin')), (3109.28, 'kelvin**2')), | ||
3647 | 799 | (((100, 'degF'), (10, 'degC')), (88039.20, 'kelvin**2')), | ||
3648 | 800 | (((100, 'degF'), (10, 'degF')), (81129.69, 'kelvin**2')), | ||
3649 | 801 | (((100, 'degF'), (10, 'degR')), (3109.28, 'kelvin*degR')), | ||
3650 | 802 | (((100, 'degF'), (10, 'delta_degC')), (3109.28, 'kelvin*delta_degC')), | ||
3651 | 803 | (((100, 'degF'), (10, 'delta_degF')), (3109.28, 'kelvin*delta_degF')), | ||
3652 | 804 | |||
3653 | 805 | (((100, 'degR'), (10, 'degC')), (28315., 'degR*kelvin')), | ||
3654 | 806 | (((100, 'degR'), (10, 'degF')), (26092.78, 'degR*kelvin')), | ||
3655 | 807 | |||
3656 | 808 | (((100, 'delta_degC'), (10, 'degC')), (28315., 'delta_degC*kelvin')), | ||
3657 | 809 | (((100, 'delta_degC'), (10, 'degF')), (26092.78, 'delta_degC*kelvin')), | ||
3658 | 810 | |||
3659 | 811 | (((100, 'delta_degF'), (10, 'degC')), (28315., 'delta_degF*kelvin')), | ||
3660 | 812 | (((100, 'delta_degF'), (10, 'degF')), (26092.78, 'delta_degF*kelvin')), | ||
3661 | 813 | ] | ||
3662 | 814 | |||
3663 | 815 | @ParameterizedTestCase.parameterize( | ||
3664 | 816 | ("input", "expected_output"), | ||
3665 | 817 | multiplications_with_autoconvert_to_baseunit) | ||
3666 | 818 | def test_multiplication_with_autoconvert(self, input_tuple, expected): | ||
3667 | 819 | self.ureg.autoconvert_offset_to_baseunit = True | ||
3668 | 820 | qin1, qin2 = input_tuple | ||
3669 | 821 | q1, q2 = self.Q_(*qin1), self.Q_(*qin2) | ||
3670 | 822 | input_tuple = q1, q2 | ||
3671 | 823 | if expected == 'error': | ||
3672 | 824 | self.assertRaises(OffsetUnitCalculusError, op.mul, q1, q2) | ||
3673 | 825 | else: | ||
3674 | 826 | expected = self.Q_(*expected) | ||
3675 | 827 | self.assertEqual(op.mul(q1, q2).units, expected.units) | ||
3676 | 828 | self.assertQuantityAlmostEqual(op.mul(q1, q2), expected, | ||
3677 | 829 | atol=0.01) | ||
3678 | 830 | |||
3679 | 831 | @helpers.requires_numpy() | ||
3680 | 832 | @ParameterizedTestCase.parameterize( | ||
3681 | 833 | ("input", "expected_output"), | ||
3682 | 834 | multiplications_with_autoconvert_to_baseunit) | ||
3683 | 835 | def test_inplace_multiplication_with_autoconvert(self, input_tuple, expected): | ||
3684 | 836 | self.ureg.autoconvert_offset_to_baseunit = True | ||
3685 | 837 | (q1v, q1u), (q2v, q2u) = input_tuple | ||
3686 | 838 | # update input tuple with new values to have correct values on failure | ||
3687 | 839 | input_tuple = ((np.array([q1v]*2, dtype=np.float), q1u), | ||
3688 | 840 | (np.array([q2v]*2, dtype=np.float), q2u)) | ||
3689 | 841 | Q_ = self.Q_ | ||
3690 | 842 | qin1, qin2 = input_tuple | ||
3691 | 843 | q1, q2 = Q_(*qin1), Q_(*qin2) | ||
3692 | 844 | q1_cp = copy.copy(q1) | ||
3693 | 845 | if expected == 'error': | ||
3694 | 846 | self.assertRaises(OffsetUnitCalculusError, op.imul, q1_cp, q2) | ||
3695 | 847 | else: | ||
3696 | 848 | expected = np.array([expected[0]]*2, dtype=np.float), expected[1] | ||
3697 | 849 | self.assertEqual(op.imul(q1_cp, q2).units, Q_(*expected).units) | ||
3698 | 850 | q1_cp = copy.copy(q1) | ||
3699 | 851 | self.assertQuantityAlmostEqual(op.imul(q1_cp, q2), Q_(*expected), | ||
3700 | 852 | atol=0.01) | ||
3701 | 853 | |||
3702 | 854 | multiplications_with_scalar = [ | ||
3703 | 855 | (((10, 'kelvin'), 2), (20., 'kelvin')), | ||
3704 | 856 | (((10, 'kelvin**2'), 2), (20., 'kelvin**2')), | ||
3705 | 857 | (((10, 'degC'), 2), (20., 'degC')), | ||
3706 | 858 | (((10, '1/degC'), 2), 'error'), | ||
3707 | 859 | (((10, 'degC**0.5'), 2), 'error'), | ||
3708 | 860 | (((10, 'degC**2'), 2), 'error'), | ||
3709 | 861 | (((10, 'degC**-2'), 2), 'error'), | ||
3710 | 862 | ] | ||
3711 | 863 | |||
3712 | 864 | @ParameterizedTestCase.parameterize( | ||
3713 | 865 | ("input", "expected_output"), multiplications_with_scalar) | ||
3714 | 866 | def test_multiplication_with_scalar(self, input_tuple, expected): | ||
3715 | 867 | self.ureg.default_as_delta = False | ||
3716 | 868 | in1, in2 = input_tuple | ||
3717 | 869 | if type(in1) is tuple: | ||
3718 | 870 | in1, in2 = self.Q_(*in1), in2 | ||
3719 | 871 | else: | ||
3720 | 872 | in1, in2 = in1, self.Q_(*in2) | ||
3721 | 873 | input_tuple = in1, in2 # update input_tuple for better tracebacks | ||
3722 | 874 | if expected == 'error': | ||
3723 | 875 | self.assertRaises(OffsetUnitCalculusError, op.mul, in1, in2) | ||
3724 | 876 | else: | ||
3725 | 877 | expected = self.Q_(*expected) | ||
3726 | 878 | self.assertEqual(op.mul(in1, in2).units, expected.units) | ||
3727 | 879 | self.assertQuantityAlmostEqual(op.mul(in1, in2), expected, | ||
3728 | 880 | atol=0.01) | ||
3729 | 881 | |||
3730 | 882 | divisions_with_scalar = [ # without / with autoconvert to base unit | ||
3731 | 883 | (((10, 'kelvin'), 2), [(5., 'kelvin'), (5., 'kelvin')]), | ||
3732 | 884 | (((10, 'kelvin**2'), 2), [(5., 'kelvin**2'), (5., 'kelvin**2')]), | ||
3733 | 885 | (((10, 'degC'), 2), ['error', 'error']), | ||
3734 | 886 | (((10, 'degC**2'), 2), ['error', 'error']), | ||
3735 | 887 | (((10, 'degC**-2'), 2), ['error', 'error']), | ||
3736 | 888 | |||
3737 | 889 | ((2, (10, 'kelvin')), [(0.2, '1/kelvin'), (0.2, '1/kelvin')]), | ||
3738 | 890 | ((2, (10, 'degC')), ['error', (2/283.15, '1/kelvin')]), | ||
3739 | 891 | ((2, (10, 'degC**2')), ['error', 'error']), | ||
3740 | 892 | ((2, (10, 'degC**-2')), ['error', 'error']), | ||
3741 | 893 | ] | ||
3742 | 894 | |||
3743 | 895 | @ParameterizedTestCase.parameterize( | ||
3744 | 896 | ("input", "expected_output"), divisions_with_scalar) | ||
3745 | 897 | def test_division_with_scalar(self, input_tuple, expected): | ||
3746 | 898 | self.ureg.default_as_delta = False | ||
3747 | 899 | in1, in2 = input_tuple | ||
3748 | 900 | if type(in1) is tuple: | ||
3749 | 901 | in1, in2 = self.Q_(*in1), in2 | ||
3750 | 902 | else: | ||
3751 | 903 | in1, in2 = in1, self.Q_(*in2) | ||
3752 | 904 | input_tuple = in1, in2 # update input_tuple for better tracebacks | ||
3753 | 905 | expected_copy = expected[:] | ||
3754 | 906 | for i, mode in enumerate([False, True]): | ||
3755 | 907 | self.ureg.autoconvert_offset_to_baseunit = mode | ||
3756 | 908 | if expected_copy[i] == 'error': | ||
3757 | 909 | self.assertRaises(OffsetUnitCalculusError, op.truediv, in1, in2) | ||
3758 | 910 | else: | ||
3759 | 911 | expected = self.Q_(*expected_copy[i]) | ||
3760 | 912 | self.assertEqual(op.truediv(in1, in2).units, expected.units) | ||
3761 | 913 | self.assertQuantityAlmostEqual(op.truediv(in1, in2), expected) | ||
3762 | 914 | |||
3763 | 915 | exponentiation = [ # resuls without / with autoconvert | ||
3764 | 916 | (((10, 'degC'), 1), [(10, 'degC'), (10, 'degC')]), | ||
3765 | 917 | (((10, 'degC'), 0.5), ['error', (283.15**0.5, 'kelvin**0.5')]), | ||
3766 | 918 | (((10, 'degC'), 0), [(1., ''), (1., '')]), | ||
3767 | 919 | (((10, 'degC'), -1), ['error', (1/(10+273.15), 'kelvin**-1')]), | ||
3768 | 920 | (((10, 'degC'), -2), ['error', (1/(10+273.15)**2., 'kelvin**-2')]), | ||
3769 | 921 | ((( 0, 'degC'), -2), ['error', (1/(273.15)**2, 'kelvin**-2')]), | ||
3770 | 922 | (((10, 'degC'), (2, '')), ['error', ((283.15)**2, 'kelvin**2')]), | ||
3771 | 923 | (((10, 'degC'), (10, 'degK')), ['error', 'error']), | ||
3772 | 924 | |||
3773 | 925 | (((10, 'kelvin'), (2, '')), [(100., 'kelvin**2'), (100., 'kelvin**2')]), | ||
3774 | 926 | |||
3775 | 927 | (( 2, (2, 'kelvin')), ['error', 'error']), | ||
3776 | 928 | (( 2, (500., 'millikelvin/kelvin')), [2**0.5, 2**0.5]), | ||
3777 | 929 | (( 2, (0.5, 'kelvin/kelvin')), [2**0.5, 2**0.5]), | ||
3778 | 930 | (((10, 'degC'), (500., 'millikelvin/kelvin')), | ||
3779 | 931 | ['error', (283.15**0.5, 'kelvin**0.5')]), | ||
3780 | 932 | ] | ||
3781 | 933 | |||
3782 | 934 | @ParameterizedTestCase.parameterize( | ||
3783 | 935 | ("input", "expected_output"), exponentiation) | ||
3784 | 936 | def test_exponentiation(self, input_tuple, expected): | ||
3785 | 937 | self.ureg.default_as_delta = False | ||
3786 | 938 | in1, in2 = input_tuple | ||
3787 | 939 | if type(in1) is tuple and type(in2) is tuple: | ||
3788 | 940 | in1, in2 = self.Q_(*in1), self.Q_(*in2) | ||
3789 | 941 | elif not type(in1) is tuple and type(in2) is tuple: | ||
3790 | 942 | in2 = self.Q_(*in2) | ||
3791 | 943 | else: | ||
3792 | 944 | in1 = self.Q_(*in1) | ||
3793 | 945 | input_tuple = in1, in2 | ||
3794 | 946 | expected_copy = expected[:] | ||
3795 | 947 | for i, mode in enumerate([False, True]): | ||
3796 | 948 | self.ureg.autoconvert_offset_to_baseunit = mode | ||
3797 | 949 | if expected_copy[i] == 'error': | ||
3798 | 950 | self.assertRaises((OffsetUnitCalculusError, | ||
3799 | 951 | DimensionalityError), op.pow, in1, in2) | ||
3800 | 952 | else: | ||
3801 | 953 | if type(expected_copy[i]) is tuple: | ||
3802 | 954 | expected = self.Q_(*expected_copy[i]) | ||
3803 | 955 | self.assertEqual(op.pow(in1, in2).units, expected.units) | ||
3804 | 956 | else: | ||
3805 | 957 | expected = expected_copy[i] | ||
3806 | 958 | self.assertQuantityAlmostEqual(op.pow(in1, in2), expected) | ||
3807 | 959 | |||
3808 | 960 | @helpers.requires_numpy() | ||
3809 | 961 | @ParameterizedTestCase.parameterize( | ||
3810 | 962 | ("input", "expected_output"), exponentiation) | ||
3811 | 963 | def test_inplace_exponentiation(self, input_tuple, expected): | ||
3812 | 964 | self.ureg.default_as_delta = False | ||
3813 | 965 | in1, in2 = input_tuple | ||
3814 | 966 | if type(in1) is tuple and type(in2) is tuple: | ||
3815 | 967 | (q1v, q1u), (q2v, q2u) = in1, in2 | ||
3816 | 968 | in1 = self.Q_(*(np.array([q1v]*2, dtype=np.float), q1u)) | ||
3817 | 969 | in2 = self.Q_(q2v, q2u) | ||
3818 | 970 | elif not type(in1) is tuple and type(in2) is tuple: | ||
3819 | 971 | in2 = self.Q_(*in2) | ||
3820 | 972 | else: | ||
3821 | 973 | in1 = self.Q_(*in1) | ||
3822 | 974 | |||
3823 | 975 | input_tuple = in1, in2 | ||
3824 | 976 | |||
3825 | 977 | expected_copy = expected[:] | ||
3826 | 978 | for i, mode in enumerate([False, True]): | ||
3827 | 979 | self.ureg.autoconvert_offset_to_baseunit = mode | ||
3828 | 980 | in1_cp = copy.copy(in1) | ||
3829 | 981 | if expected_copy[i] == 'error': | ||
3830 | 982 | self.assertRaises((OffsetUnitCalculusError, | ||
3831 | 983 | DimensionalityError), op.ipow, in1_cp, in2) | ||
3832 | 984 | else: | ||
3833 | 985 | if type(expected_copy[i]) is tuple: | ||
3834 | 986 | expected = self.Q_(np.array([expected_copy[i][0]]*2, | ||
3835 | 987 | dtype=np.float), | ||
3836 | 988 | expected_copy[i][1]) | ||
3837 | 989 | self.assertEqual(op.ipow(in1_cp, in2).units, expected.units) | ||
3838 | 990 | else: | ||
3839 | 991 | expected = np.array([expected_copy[i]]*2, dtype=np.float) | ||
3840 | 992 | |||
3841 | 993 | |||
3842 | 994 | in1_cp = copy.copy(in1) | ||
3843 | 995 | self.assertQuantityAlmostEqual(op.ipow(in1_cp, in2), expected) | ||
3844 | 453 | 996 | ||
3845 | === modified file 'pint/testsuite/test_umath.py' | |||
3846 | --- pint/testsuite/test_umath.py 2014-09-05 23:26:05 +0000 | |||
3847 | +++ pint/testsuite/test_umath.py 2015-01-07 15:51:38 +0000 | |||
3848 | @@ -52,17 +52,29 @@ | |||
3849 | 52 | except Exception as e: | 52 | except Exception as e: |
3850 | 53 | self.assertFalse(True, msg='{0} not raised but {1}\n{2}'.format(ExcType, e, msg)) | 53 | self.assertFalse(True, msg='{0} not raised but {1}\n{2}'.format(ExcType, e, msg)) |
3851 | 54 | 54 | ||
3852 | 55 | def _testn(self, func, ok_with, raise_with=(), results=None): | ||
3853 | 56 | self._test1(func, ok_with, raise_with, output_units=None, results=results) | ||
3854 | 57 | |||
3855 | 58 | def _test1(self, func, ok_with, raise_with=(), output_units='same', results=None, rtol=1e-6): | 55 | def _test1(self, func, ok_with, raise_with=(), output_units='same', results=None, rtol=1e-6): |
3856 | 56 | """Test function that takes a single argument and returns Quantity. | ||
3857 | 57 | |||
3858 | 58 | :param func: function callable. | ||
3859 | 59 | :param ok_with: iterables of values that work fine. | ||
3860 | 60 | :param raise_with: iterables of values that raise exceptions. | ||
3861 | 61 | :param output_units: units to be used when building results. | ||
3862 | 62 | 'same': ok_with[n].units (default). | ||
3863 | 63 | is float: ok_with[n].units ** output_units. | ||
3864 | 64 | None: no output units, the result should be an ndarray. | ||
3865 | 65 | Other value will be parsed as unit. | ||
3866 | 66 | :param results: iterable of results. | ||
3867 | 67 | If None, the result will be obtained by applying | ||
3868 | 68 | func to each ok_with value | ||
3869 | 69 | :param rtol: relative tolerance. | ||
3870 | 70 | """ | ||
3871 | 59 | if results is None: | 71 | if results is None: |
3872 | 60 | results = [None, ] * len(ok_with) | 72 | results = [None, ] * len(ok_with) |
3873 | 61 | for x1, res in zip(ok_with, results): | 73 | for x1, res in zip(ok_with, results): |
3874 | 62 | err_msg = 'At {0} with {1}'.format(func.__name__, x1) | 74 | err_msg = 'At {0} with {1}'.format(func.__name__, x1) |
3875 | 63 | if output_units == 'same': | 75 | if output_units == 'same': |
3876 | 64 | ou = x1.units | 76 | ou = x1.units |
3878 | 65 | elif isinstance(output_units, int): | 77 | elif isinstance(output_units, (int, float)): |
3879 | 66 | ou = x1.units ** output_units | 78 | ou = x1.units ** output_units |
3880 | 67 | else: | 79 | else: |
3881 | 68 | ou = output_units | 80 | ou = output_units |
3882 | @@ -70,20 +82,45 @@ | |||
3883 | 70 | qm = func(x1) | 82 | qm = func(x1) |
3884 | 71 | if res is None: | 83 | if res is None: |
3885 | 72 | res = func(x1.magnitude) | 84 | res = func(x1.magnitude) |
3887 | 73 | if ou: | 85 | if ou is not None: |
3888 | 74 | res = self.Q_(res, ou) | 86 | res = self.Q_(res, ou) |
3894 | 75 | if isinstance(res, self.Q_): | 87 | |
3895 | 76 | self.assertIsInstance(qm, self.Q_, msg=err_msg + ' {0!r} is not Quantity'.format(qm)) | 88 | self.assertQuantityAlmostEqual(qm, res, rtol=rtol, msg=err_msg) |
3891 | 77 | qm = qm.magnitude | ||
3892 | 78 | res = res.magnitude | ||
3893 | 79 | np.testing.assert_allclose(qm, res, rtol=rtol, err_msg=err_msg) | ||
3896 | 80 | 89 | ||
3897 | 81 | for x1 in raise_with: | 90 | for x1 in raise_with: |
3898 | 82 | self.assertRaisesMsg('At {0} with {1}'.format(func.__name__, x1), | 91 | self.assertRaisesMsg('At {0} with {1}'.format(func.__name__, x1), |
3899 | 83 | ValueError, func, x1) | 92 | ValueError, func, x1) |
3900 | 84 | 93 | ||
3901 | 94 | def _testn(self, func, ok_with, raise_with=(), results=None): | ||
3902 | 95 | """Test function that takes a single argument and returns and ndarray (not a Quantity) | ||
3903 | 96 | |||
3904 | 97 | :param func: function callable. | ||
3905 | 98 | :param ok_with: iterables of values that work fine. | ||
3906 | 99 | :param raise_with: iterables of values that raise exceptions. | ||
3907 | 100 | :param results: iterable of results. | ||
3908 | 101 | If None, the result will be obtained by applying | ||
3909 | 102 | func to each ok_with value | ||
3910 | 103 | """ | ||
3911 | 104 | self._test1(func, ok_with, raise_with, output_units=None, results=results) | ||
3912 | 105 | |||
3913 | 85 | def _test1_2o(self, func, ok_with, raise_with=(), output_units=('same', 'same'), | 106 | def _test1_2o(self, func, ok_with, raise_with=(), output_units=('same', 'same'), |
3914 | 86 | results=None, rtol=1e-6): | 107 | results=None, rtol=1e-6): |
3915 | 108 | """Test functions that takes a single argument and return two Quantities. | ||
3916 | 109 | |||
3917 | 110 | :param func: function callable. | ||
3918 | 111 | :param ok_with: iterables of values that work fine. | ||
3919 | 112 | :param raise_with: iterables of values that raise exceptions. | ||
3920 | 113 | :param output_units: tuple of units to be used when building the result tuple. | ||
3921 | 114 | 'same': ok_with[n].units (default). | ||
3922 | 115 | is float: ok_with[n].units ** output_units. | ||
3923 | 116 | None: no output units, the result should be an ndarray. | ||
3924 | 117 | Other value will be parsed as unit. | ||
3925 | 118 | :param results: iterable of results. | ||
3926 | 119 | If None, the result will be obtained by applying | ||
3927 | 120 | func to each ok_with value | ||
3928 | 121 | :param rtol: relative tolerance. | ||
3929 | 122 | """ | ||
3930 | 123 | |||
3931 | 87 | if results is None: | 124 | if results is None: |
3932 | 88 | results = [None, ] * len(ok_with) | 125 | results = [None, ] * len(ok_with) |
3933 | 89 | for x1, res in zip(ok_with, results): | 126 | for x1, res in zip(ok_with, results): |
3934 | @@ -95,26 +132,35 @@ | |||
3935 | 95 | for ndx, (qm, re, ou) in enumerate(zip(qms, res, output_units)): | 132 | for ndx, (qm, re, ou) in enumerate(zip(qms, res, output_units)): |
3936 | 96 | if ou == 'same': | 133 | if ou == 'same': |
3937 | 97 | ou = x1.units | 134 | ou = x1.units |
3939 | 98 | elif isinstance(ou, int): | 135 | elif isinstance(ou, (int, float)): |
3940 | 99 | ou = x1.units ** ou | 136 | ou = x1.units ** ou |
3941 | 100 | 137 | ||
3942 | 101 | if ou is not None: | 138 | if ou is not None: |
3943 | 102 | re = self.Q_(re, ou) | 139 | re = self.Q_(re, ou) |
3944 | 103 | 140 | ||
3950 | 104 | if isinstance(re, self.Q_): | 141 | self.assertQuantityAlmostEqual(qm, re, rtol=rtol, msg=err_msg) |
3946 | 105 | self.assertIsInstance(qm, self.Q_, msg=err_msg) | ||
3947 | 106 | qm = qm.magnitude | ||
3948 | 107 | re = re.magnitude | ||
3949 | 108 | np.testing.assert_allclose(qm, re, rtol=rtol, err_msg=err_msg) | ||
3951 | 109 | 142 | ||
3952 | 110 | for x1 in raise_with: | 143 | for x1 in raise_with: |
3953 | 111 | self.assertRaisesMsg('At {0} with {1}'.format(func.__name__, x1), | 144 | self.assertRaisesMsg('At {0} with {1}'.format(func.__name__, x1), |
3954 | 112 | ValueError, func, x1) | 145 | ValueError, func, x1) |
3955 | 113 | 146 | ||
3956 | 114 | def _testn2(self, func, x1, ok_with, raise_with=()): | ||
3957 | 115 | self._test2(func, x1, ok_with, raise_with, output_units=None) | ||
3958 | 116 | |||
3959 | 117 | def _test2(self, func, x1, ok_with, raise_with=(), output_units='same', rtol=1e-6, convert2=True): | 147 | def _test2(self, func, x1, ok_with, raise_with=(), output_units='same', rtol=1e-6, convert2=True): |
3960 | 148 | """Test function that takes two arguments and return a Quantity. | ||
3961 | 149 | |||
3962 | 150 | :param func: function callable. | ||
3963 | 151 | :param x1: first argument of func. | ||
3964 | 152 | :param ok_with: iterables of values that work fine. | ||
3965 | 153 | :param raise_with: iterables of values that raise exceptions. | ||
3966 | 154 | :param output_units: units to be used when building results. | ||
3967 | 155 | 'same': x1.units (default). | ||
3968 | 156 | 'prod': x1.units * ok_with[n].units | ||
3969 | 157 | 'div': x1.units / ok_with[n].units | ||
3970 | 158 | 'second': x1.units * ok_with[n] | ||
3971 | 159 | None: no output units, the result should be an ndarray. | ||
3972 | 160 | Other value will be parsed as unit. | ||
3973 | 161 | :param rtol: relative tolerance. | ||
3974 | 162 | :param convert2: if the ok_with[n] should be converted to x1.units. | ||
3975 | 163 | """ | ||
3976 | 118 | for x2 in ok_with: | 164 | for x2 in ok_with: |
3977 | 119 | err_msg = 'At {0} with {1} and {2}'.format(func.__name__, x1, x2) | 165 | err_msg = 'At {0} with {1} and {2}'.format(func.__name__, x1, x2) |
3978 | 120 | if output_units == 'same': | 166 | if output_units == 'same': |
3979 | @@ -136,18 +182,25 @@ | |||
3980 | 136 | m2 = getattr(x2, 'magnitude', x2) | 182 | m2 = getattr(x2, 'magnitude', x2) |
3981 | 137 | 183 | ||
3982 | 138 | res = func(x1.magnitude, m2) | 184 | res = func(x1.magnitude, m2) |
3984 | 139 | if ou: | 185 | if ou is not None: |
3985 | 140 | res = self.Q_(res, ou) | 186 | res = self.Q_(res, ou) |
3991 | 141 | if isinstance(res, self.Q_): | 187 | |
3992 | 142 | self.assertIsInstance(qm, self.Q_, msg=err_msg) | 188 | self.assertQuantityAlmostEqual(qm, res, rtol=rtol, msg=err_msg) |
3988 | 143 | qm = qm.magnitude | ||
3989 | 144 | res = res.magnitude | ||
3990 | 145 | np.testing.assert_allclose(qm, res, rtol=rtol, err_msg=err_msg) | ||
3993 | 146 | 189 | ||
3994 | 147 | for x2 in raise_with: | 190 | for x2 in raise_with: |
3995 | 148 | self.assertRaisesMsg('At {0} with {1} and {2}'.format(func.__name__, x1, x2), | 191 | self.assertRaisesMsg('At {0} with {1} and {2}'.format(func.__name__, x1, x2), |
3996 | 149 | ValueError, func, x1, x2) | 192 | ValueError, func, x1, x2) |
3997 | 150 | 193 | ||
3998 | 194 | def _testn2(self, func, x1, ok_with, raise_with=()): | ||
3999 | 195 | """Test function that takes two arguments and return a ndarray. | ||
4000 | 196 | |||
4001 | 197 | :param func: function callable. | ||
4002 | 198 | :param x1: first argument of func. | ||
4003 | 199 | :param ok_with: iterables of values that work fine. | ||
4004 | 200 | :param raise_with: iterables of values that raise exceptions. | ||
4005 | 201 | """ | ||
4006 | 202 | self._test2(func, x1, ok_with, raise_with, output_units=None) | ||
4007 | 203 | |||
4008 | 151 | 204 | ||
4009 | 152 | @helpers.requires_numpy() | 205 | @helpers.requires_numpy() |
4010 | 153 | class TestMathUfuncs(TestUFuncs): | 206 | class TestMathUfuncs(TestUFuncs): |
4011 | @@ -248,7 +301,7 @@ | |||
4012 | 248 | self.q1, | 301 | self.q1, |
4013 | 249 | (self.q2, self.qs, self.qless), | 302 | (self.q2, self.qs, self.qless), |
4014 | 250 | (), | 303 | (), |
4016 | 251 | 'div', convert2=False) | 304 | 'same', convert2=False) |
4017 | 252 | 305 | ||
4018 | 253 | def test_mod(self): | 306 | def test_mod(self): |
4019 | 254 | self._test2(np.mod, | 307 | self._test2(np.mod, |
4020 | @@ -322,7 +375,7 @@ | |||
4021 | 322 | self._test1(np.sqrt, | 375 | self._test1(np.sqrt, |
4022 | 323 | (self.q2, self.qs, self.qless, self.qi), | 376 | (self.q2, self.qs, self.qless, self.qi), |
4023 | 324 | (), | 377 | (), |
4025 | 325 | 'same') | 378 | 0.5) |
4026 | 326 | 379 | ||
4027 | 327 | def test_square(self): | 380 | def test_square(self): |
4028 | 328 | self._test1(np.square, | 381 | self._test1(np.square, |
4029 | @@ -334,7 +387,7 @@ | |||
4030 | 334 | self._test1(np.reciprocal, | 387 | self._test1(np.reciprocal, |
4031 | 335 | (self.q2, self.qs, self.qless, self.qi), | 388 | (self.q2, self.qs, self.qless, self.qi), |
4032 | 336 | (), | 389 | (), |
4034 | 337 | 2) | 390 | -1) |
4035 | 338 | 391 | ||
4036 | 339 | 392 | ||
4037 | 340 | @helpers.requires_numpy() | 393 | @helpers.requires_numpy() |
4038 | @@ -469,10 +522,16 @@ | |||
4039 | 469 | ), (self.ureg.m, ), 'radians') | 522 | ), (self.ureg.m, ), 'radians') |
4040 | 470 | 523 | ||
4041 | 471 | def test_rad2deg(self): | 524 | def test_rad2deg(self): |
4046 | 472 | self._test1(np.rad2deg, (np.arange(0, pi/2, pi/4) * self.ureg.dimensionless, | 525 | self._test1(np.rad2deg, |
4047 | 473 | np.arange(0, pi/2, pi/4) * self.ureg.radian, | 526 | (np.arange(0, pi/2, pi/4) * self.ureg.dimensionless, |
4048 | 474 | np.arange(0, pi/2, pi/4) * self.ureg.mm / self.ureg.m | 527 | np.arange(0, pi/2, pi/4) * self.ureg.radian, |
4049 | 475 | ), (self.ureg.m, ), 'degree', results=(None, None, np.rad2deg(np.arange(0, pi/2, pi/4)*0.001))) | 528 | np.arange(0, pi/2, pi/4) * self.ureg.mm / self.ureg.m, |
4050 | 529 | ), | ||
4051 | 530 | (self.ureg.m, ), 'degree', | ||
4052 | 531 | results=(None, | ||
4053 | 532 | None, | ||
4054 | 533 | np.rad2deg(np.arange(0, pi/2, pi/4)*0.001) * self.ureg.degree, | ||
4055 | 534 | )) | ||
4056 | 476 | 535 | ||
4057 | 477 | 536 | ||
4058 | 478 | 537 | ||
4059 | 479 | 538 | ||
4060 | === modified file 'pint/testsuite/test_unit.py' | |||
4061 | --- pint/testsuite/test_unit.py 2014-09-05 23:26:05 +0000 | |||
4062 | +++ pint/testsuite/test_unit.py 2015-01-07 15:51:38 +0000 | |||
4063 | @@ -12,8 +12,9 @@ | |||
4064 | 12 | DimensionDefinition, _freeze, Converter, UnitRegistry, | 12 | DimensionDefinition, _freeze, Converter, UnitRegistry, |
4065 | 13 | LazyRegistry, ParserHelper) | 13 | LazyRegistry, ParserHelper) |
4066 | 14 | from pint import DimensionalityError, UndefinedUnitError | 14 | from pint import DimensionalityError, UndefinedUnitError |
4068 | 15 | from pint.compat import u, unittest, np | 15 | from pint.compat import u, unittest, np, string_types |
4069 | 16 | from pint.testsuite import QuantityTestCase, helpers, BaseTestCase | 16 | from pint.testsuite import QuantityTestCase, helpers, BaseTestCase |
4070 | 17 | from pint.testsuite.parameterized import ParameterizedTestCase | ||
4071 | 17 | 18 | ||
4072 | 18 | 19 | ||
4073 | 19 | class TestConverter(BaseTestCase): | 20 | class TestConverter(BaseTestCase): |
4074 | @@ -231,6 +232,9 @@ | |||
4075 | 231 | 232 | ||
4076 | 232 | FORCE_NDARRAY = False | 233 | FORCE_NDARRAY = False |
4077 | 233 | 234 | ||
4078 | 235 | def setup(self): | ||
4079 | 236 | self.ureg.autoconvert_offset_to_baseunit = False | ||
4080 | 237 | |||
4081 | 234 | def test_base(self): | 238 | def test_base(self): |
4082 | 235 | ureg = UnitRegistry(None) | 239 | ureg = UnitRegistry(None) |
4083 | 236 | ureg.define('meter = [length]') | 240 | ureg.define('meter = [length]') |
4084 | @@ -324,16 +328,16 @@ | |||
4085 | 324 | q = self.Q_(1, 'g/(m**2*s)') | 328 | q = self.Q_(1, 'g/(m**2*s)') |
4086 | 325 | self.assertEqual(self.Q_(q.magnitude, str(q.units)), q) | 329 | self.assertEqual(self.Q_(q.magnitude, str(q.units)), q) |
4087 | 326 | 330 | ||
4089 | 327 | def test_to_delta(self): | 331 | def test_as_delta(self): |
4090 | 328 | parse = self.ureg.parse_units | 332 | parse = self.ureg.parse_units |
4099 | 329 | self.assertEqual(parse('kelvin', to_delta=True), UnitsContainer(kelvin=1)) | 333 | self.assertEqual(parse('kelvin', as_delta=True), UnitsContainer(kelvin=1)) |
4100 | 330 | self.assertEqual(parse('kelvin', to_delta=False), UnitsContainer(kelvin=1)) | 334 | self.assertEqual(parse('kelvin', as_delta=False), UnitsContainer(kelvin=1)) |
4101 | 331 | self.assertEqual(parse('kelvin**(-1)', to_delta=True), UnitsContainer(kelvin=-1)) | 335 | self.assertEqual(parse('kelvin**(-1)', as_delta=True), UnitsContainer(kelvin=-1)) |
4102 | 332 | self.assertEqual(parse('kelvin**(-1)', to_delta=False), UnitsContainer(kelvin=-1)) | 336 | self.assertEqual(parse('kelvin**(-1)', as_delta=False), UnitsContainer(kelvin=-1)) |
4103 | 333 | self.assertEqual(parse('kelvin**2', to_delta=True), UnitsContainer(kelvin=2)) | 337 | self.assertEqual(parse('kelvin**2', as_delta=True), UnitsContainer(kelvin=2)) |
4104 | 334 | self.assertEqual(parse('kelvin**2', to_delta=False), UnitsContainer(kelvin=2)) | 338 | self.assertEqual(parse('kelvin**2', as_delta=False), UnitsContainer(kelvin=2)) |
4105 | 335 | self.assertEqual(parse('kelvin*meter', to_delta=True), UnitsContainer(kelvin=1, meter= 1)) | 339 | self.assertEqual(parse('kelvin*meter', as_delta=True), UnitsContainer(kelvin=1, meter= 1)) |
4106 | 336 | self.assertEqual(parse('kelvin*meter', to_delta=False), UnitsContainer(kelvin=1, meter=1)) | 340 | self.assertEqual(parse('kelvin*meter', as_delta=False), UnitsContainer(kelvin=1, meter=1)) |
4107 | 337 | 341 | ||
4108 | 338 | def test_name(self): | 342 | def test_name(self): |
4109 | 339 | self.assertRaises(UndefinedUnitError, self.ureg.get_name, 'asdf') | 343 | self.assertRaises(UndefinedUnitError, self.ureg.get_name, 'asdf') |
4110 | @@ -357,18 +361,6 @@ | |||
4111 | 357 | self.assertEqual(self.ureg.get_symbol('international_foot'), 'ft') | 361 | self.assertEqual(self.ureg.get_symbol('international_foot'), 'ft') |
4112 | 358 | self.assertEqual(self.ureg.get_symbol('international_inch'), 'in') | 362 | self.assertEqual(self.ureg.get_symbol('international_inch'), 'in') |
4113 | 359 | 363 | ||
4114 | 360 | @unittest.expectedFailure | ||
4115 | 361 | def test_delta_in_diff(self): | ||
4116 | 362 | """This might be supported in future versions | ||
4117 | 363 | """ | ||
4118 | 364 | xk = 1 * self.ureg.kelvin | ||
4119 | 365 | yk = 2 * self.ureg.kelvin | ||
4120 | 366 | yf = yk.to('degF') | ||
4121 | 367 | yc = yk.to('degC') | ||
4122 | 368 | self.assertEqual(yk - xk, 1 * self.ureg.kelvin) | ||
4123 | 369 | self.assertEqual(yf - xk, 1 * self.ureg.kelvin) | ||
4124 | 370 | self.assertEqual(yc - xk, 1 * self.ureg.kelvin) | ||
4125 | 371 | |||
4126 | 372 | def test_pint(self): | 364 | def test_pint(self): |
4127 | 373 | p = self.ureg.pint | 365 | p = self.ureg.pint |
4128 | 374 | l = self.ureg.liter | 366 | l = self.ureg.liter |
4129 | @@ -440,12 +432,13 @@ | |||
4130 | 440 | self.assertEqual(h2(3, 1), (3 * ureg.meter, 1 * ureg.cm)) | 432 | self.assertEqual(h2(3, 1), (3 * ureg.meter, 1 * ureg.cm)) |
4131 | 441 | 433 | ||
4132 | 442 | def test_to_ref_vs_to(self): | 434 | def test_to_ref_vs_to(self): |
4133 | 435 | self.ureg.autoconvert_offset_to_baseunit = True | ||
4134 | 443 | q = 8. * self.ureg.inch | 436 | q = 8. * self.ureg.inch |
4135 | 444 | t = 8. * self.ureg.degF | 437 | t = 8. * self.ureg.degF |
4136 | 445 | dt = 8. * self.ureg.delta_degF | 438 | dt = 8. * self.ureg.delta_degF |
4137 | 446 | self.assertEqual(q.to('cm').magnitude, self.ureg._units['inch'].converter.to_reference(8.)) | 439 | self.assertEqual(q.to('cm').magnitude, self.ureg._units['inch'].converter.to_reference(8.)) |
4138 | 447 | self.assertEqual(t.to('kelvin').magnitude, self.ureg._units['degF'].converter.to_reference(8.)) | 440 | self.assertEqual(t.to('kelvin').magnitude, self.ureg._units['degF'].converter.to_reference(8.)) |
4140 | 448 | self.assertEqual(dt.to('delta_kelvin').magnitude, self.ureg._units['delta_degF'].converter.to_reference(8.)) | 441 | self.assertEqual(dt.to('kelvin').magnitude, self.ureg._units['delta_degF'].converter.to_reference(8.)) |
4141 | 449 | 442 | ||
4142 | 450 | def test_redefinition(self): | 443 | def test_redefinition(self): |
4143 | 451 | d = UnitRegistry().define | 444 | d = UnitRegistry().define |
4144 | @@ -473,7 +466,7 @@ | |||
4145 | 473 | # Conversions with single units take a different codepath than | 466 | # Conversions with single units take a different codepath than |
4146 | 474 | # Conversions with more than one unit. | 467 | # Conversions with more than one unit. |
4147 | 475 | src_dst1 = UnitsContainer(meter=1), UnitsContainer(inch=1) | 468 | src_dst1 = UnitsContainer(meter=1), UnitsContainer(inch=1) |
4149 | 476 | src_dst2 = UnitsContainer(meter=1, seconds=-1), UnitsContainer(inch=1, minutes=-1) | 469 | src_dst2 = UnitsContainer(meter=1, second=-1), UnitsContainer(inch=1, minute=-1) |
4150 | 477 | for src, dst in (src_dst1, src_dst2): | 470 | for src, dst in (src_dst1, src_dst2): |
4151 | 478 | v = ureg.convert(1, src, dst), | 471 | v = ureg.convert(1, src, dst), |
4152 | 479 | 472 | ||
4153 | @@ -598,3 +591,52 @@ | |||
4154 | 598 | msg = "Cannot convert from 'a' (c) to 'b' (d)msg" | 591 | msg = "Cannot convert from 'a' (c) to 'b' (d)msg" |
4155 | 599 | ex = DimensionalityError('a', 'b', 'c', 'd', 'msg') | 592 | ex = DimensionalityError('a', 'b', 'c', 'd', 'msg') |
4156 | 600 | self.assertEqual(str(ex), msg) | 593 | self.assertEqual(str(ex), msg) |
4157 | 594 | |||
4158 | 595 | |||
4159 | 596 | class TestConvertWithOffset(QuantityTestCase, ParameterizedTestCase): | ||
4160 | 597 | |||
4161 | 598 | # The dicts in convert_with_offset are used to create a UnitsContainer. | ||
4162 | 599 | # We create UnitsContainer to avoid any auto-conversion of units. | ||
4163 | 600 | convert_with_offset = [ | ||
4164 | 601 | (({'degC': 1}, {'degC': 1}), 10), | ||
4165 | 602 | (({'degC': 1}, {'kelvin': 1}), 283.15), | ||
4166 | 603 | (({'degC': 1}, {'degC': 1, 'millimeter': 1, 'meter': -1}), 'error'), | ||
4167 | 604 | (({'degC': 1}, {'kelvin': 1, 'millimeter': 1, 'meter': -1}), 283150), | ||
4168 | 605 | |||
4169 | 606 | (({'kelvin': 1}, {'degC': 1}), -263.15), | ||
4170 | 607 | (({'kelvin': 1}, {'kelvin': 1}), 10), | ||
4171 | 608 | (({'kelvin': 1}, {'degC': 1, 'millimeter': 1, 'meter': -1}), 'error'), | ||
4172 | 609 | (({'kelvin': 1}, {'kelvin': 1, 'millimeter': 1, 'meter': -1}), 10000), | ||
4173 | 610 | |||
4174 | 611 | (({'degC': 1, 'millimeter': 1, 'meter': -1}, {'degC': 1}), 'error'), | ||
4175 | 612 | (({'degC': 1, 'millimeter': 1, 'meter': -1}, {'kelvin': 1}), 'error'), | ||
4176 | 613 | (({'degC': 1, 'millimeter': 1, 'meter': -1}, {'degC': 1, 'millimeter': 1, 'meter': -1}), 10), | ||
4177 | 614 | (({'degC': 1, 'millimeter': 1, 'meter': -1}, {'kelvin': 1, 'millimeter': 1, 'meter': -1}), 'error'), | ||
4178 | 615 | |||
4179 | 616 | (({'kelvin': 1, 'millimeter': 1, 'meter': -1}, {'degC': 1}), -273.14), | ||
4180 | 617 | (({'kelvin': 1, 'millimeter': 1, 'meter': -1}, {'kelvin': 1}), 0.01), | ||
4181 | 618 | (({'kelvin': 1, 'millimeter': 1, 'meter': -1}, {'degC': 1, 'millimeter': 1, 'meter': -1}), 'error'), | ||
4182 | 619 | (({'kelvin': 1, 'millimeter': 1, 'meter': -1}, {'kelvin': 1, 'millimeter': 1, 'meter': -1}), 10), | ||
4183 | 620 | |||
4184 | 621 | (({'degC': 2}, {'kelvin': 2}), 'error'), | ||
4185 | 622 | (({'degC': 1, 'degF': 1}, {'kelvin': 2}), 'error'), | ||
4186 | 623 | (({'degC': 1, 'kelvin': 1}, {'kelvin': 2}), 'error'), | ||
4187 | 624 | ] | ||
4188 | 625 | |||
4189 | 626 | @ParameterizedTestCase.parameterize(("input", "expected_output"), | ||
4190 | 627 | convert_with_offset) | ||
4191 | 628 | def test_to_and_from_offset_units(self, input_tuple, expected): | ||
4192 | 629 | src, dst = input_tuple | ||
4193 | 630 | src, dst = UnitsContainer(src), UnitsContainer(dst) | ||
4194 | 631 | value = 10. | ||
4195 | 632 | convert = self.ureg.convert | ||
4196 | 633 | if isinstance(expected, string_types): | ||
4197 | 634 | self.assertRaises(DimensionalityError, convert, value, src, dst) | ||
4198 | 635 | if src != dst: | ||
4199 | 636 | self.assertRaises(DimensionalityError, convert, value, dst, src) | ||
4200 | 637 | else: | ||
4201 | 638 | self.assertQuantityAlmostEqual(convert(value, src, dst), | ||
4202 | 639 | expected, atol=0.001) | ||
4203 | 640 | if src != dst: | ||
4204 | 641 | self.assertQuantityAlmostEqual(convert(expected, dst, src), | ||
4205 | 642 | value, atol=0.001) | ||
4206 | 601 | 643 | ||
4207 | === modified file 'pint/unit.py' | |||
4208 | --- pint/unit.py 2014-09-05 23:26:05 +0000 | |||
4209 | +++ pint/unit.py 2015-01-07 15:51:38 +0000 | |||
4210 | @@ -87,7 +87,7 @@ | |||
4211 | 87 | """Raised when trying to convert between incompatible units. | 87 | """Raised when trying to convert between incompatible units. |
4212 | 88 | """ | 88 | """ |
4213 | 89 | 89 | ||
4215 | 90 | def __init__(self, units1, units2, dim1=None, dim2=None, extra_msg=None): | 90 | def __init__(self, units1, units2, dim1=None, dim2=None, extra_msg=''): |
4216 | 91 | super(DimensionalityError, self).__init__() | 91 | super(DimensionalityError, self).__init__() |
4217 | 92 | self.units1 = units1 | 92 | self.units1 = units1 |
4218 | 93 | self.units2 = units2 | 93 | self.units2 = units2 |
4219 | @@ -103,12 +103,25 @@ | |||
4220 | 103 | dim1 = '' | 103 | dim1 = '' |
4221 | 104 | dim2 = '' | 104 | dim2 = '' |
4222 | 105 | 105 | ||
4229 | 106 | msg = "Cannot convert from '{0}'{1} to '{2}'{3}".format(self.units1, dim1, self.units2, dim2) | 106 | msg = "Cannot convert from '{0}'{1} to '{2}'{3}" + self.extra_msg |
4230 | 107 | 107 | ||
4231 | 108 | if self.extra_msg: | 108 | return msg.format(self.units1, dim1, self.units2, dim2) |
4232 | 109 | return msg + self.extra_msg | 109 | |
4233 | 110 | 110 | ||
4234 | 111 | return msg | 111 | class OffsetUnitCalculusError(ValueError): |
4235 | 112 | """Raised on ambiguous operations with offset units. | ||
4236 | 113 | """ | ||
4237 | 114 | def __init__(self, units1, units2='', extra_msg=''): | ||
4238 | 115 | super(ValueError, self).__init__() | ||
4239 | 116 | self.units1 = units1 | ||
4240 | 117 | self.units2 = units2 | ||
4241 | 118 | self.extra_msg = extra_msg | ||
4242 | 119 | |||
4243 | 120 | def __str__(self): | ||
4244 | 121 | msg = ("Ambiguous operation with offset unit (%s)." % | ||
4245 | 122 | ', '.join(['%s' % u for u in [self.units1, self.units2] if u]) | ||
4246 | 123 | + self.extra_msg) | ||
4247 | 124 | return msg.format(self.units1, self.units2) | ||
4248 | 112 | 125 | ||
4249 | 113 | 126 | ||
4250 | 114 | class Converter(object): | 127 | class Converter(object): |
4251 | @@ -244,7 +257,7 @@ | |||
4252 | 244 | 257 | ||
4253 | 245 | 258 | ||
4254 | 246 | def _is_dim(name): | 259 | def _is_dim(name): |
4256 | 247 | return name.startswith('[') and name.endswith(']') | 260 | return name[0] == '[' and name[-1] == ']' |
4257 | 248 | 261 | ||
4258 | 249 | 262 | ||
4259 | 250 | class PrefixDefinition(Definition): | 263 | class PrefixDefinition(Definition): |
4260 | @@ -289,7 +302,7 @@ | |||
4261 | 289 | 'Base units must be referenced only to dimensions. ' | 302 | 'Base units must be referenced only to dimensions. ' |
4262 | 290 | 'Derived units must be referenced only to units.') | 303 | 'Derived units must be referenced only to units.') |
4263 | 291 | self.reference = UnitsContainer(converter.items()) | 304 | self.reference = UnitsContainer(converter.items()) |
4265 | 292 | if 'offset' in modifiers: | 305 | if modifiers.get('offset', 0.) != 0.: |
4266 | 293 | converter = OffsetConverter(converter.scale, modifiers['offset']) | 306 | converter = OffsetConverter(converter.scale, modifiers['offset']) |
4267 | 294 | else: | 307 | else: |
4268 | 295 | converter = ScaleConverter(converter.scale) | 308 | converter = ScaleConverter(converter.scale) |
4269 | @@ -445,14 +458,19 @@ | |||
4270 | 445 | Empty to load the default definition file. | 458 | Empty to load the default definition file. |
4271 | 446 | None to leave the UnitRegistry empty. | 459 | None to leave the UnitRegistry empty. |
4272 | 447 | :param force_ndarray: convert any input, scalar or not to a numpy.ndarray. | 460 | :param force_ndarray: convert any input, scalar or not to a numpy.ndarray. |
4274 | 448 | :param default_to_delta: In the context of a multiplication of units, interpret | 461 | :param default_as_delta: In the context of a multiplication of units, interpret |
4275 | 449 | non-multiplicative units as their *delta* counterparts. | 462 | non-multiplicative units as their *delta* counterparts. |
4276 | 463 | :autoconvert_offset_to_baseunit: If True converts offset units in quantites are | ||
4277 | 464 | converted to their base units in multiplicative | ||
4278 | 465 | context. If False no conversion happens. | ||
4279 | 450 | :param on_redefinition: action to take in case a unit is redefined. | 466 | :param on_redefinition: action to take in case a unit is redefined. |
4280 | 451 | 'warn', 'raise', 'ignore' | 467 | 'warn', 'raise', 'ignore' |
4281 | 452 | :type on_redefintion: str | 468 | :type on_redefintion: str |
4282 | 453 | """ | 469 | """ |
4283 | 454 | 470 | ||
4285 | 455 | def __init__(self, filename='', force_ndarray=False, default_to_delta=True, on_redefinition='warn'): | 471 | def __init__(self, filename='', force_ndarray=False, default_as_delta=True, |
4286 | 472 | autoconvert_offset_to_baseunit=False, | ||
4287 | 473 | on_redefinition='warn'): | ||
4288 | 456 | self.Quantity = build_quantity_class(self, force_ndarray) | 474 | self.Quantity = build_quantity_class(self, force_ndarray) |
4289 | 457 | self.Measurement = build_measurement_class(self, force_ndarray) | 475 | self.Measurement = build_measurement_class(self, force_ndarray) |
4290 | 458 | 476 | ||
4291 | @@ -491,9 +509,16 @@ | |||
4292 | 491 | #: Maps dimensionality (_freeze(UnitsContainer)) to Units (_freeze(UnitsContainer)) | 509 | #: Maps dimensionality (_freeze(UnitsContainer)) to Units (_freeze(UnitsContainer)) |
4293 | 492 | self._dimensionality_cache = TransformDict(_freeze) | 510 | self._dimensionality_cache = TransformDict(_freeze) |
4294 | 493 | 511 | ||
4295 | 512 | #: Cache the unit name associated to user input. ('mV' -> 'millivolt') | ||
4296 | 513 | self._parse_unit_cache = dict() | ||
4297 | 514 | |||
4298 | 494 | #: When performing a multiplication of units, interpret | 515 | #: When performing a multiplication of units, interpret |
4299 | 495 | #: non-multiplicative units as their *delta* counterparts. | 516 | #: non-multiplicative units as their *delta* counterparts. |
4301 | 496 | self.default_to_delta = default_to_delta | 517 | self.default_as_delta = default_as_delta |
4302 | 518 | |||
4303 | 519 | # Determines if quantities with offset units are converted to their | ||
4304 | 520 | # base units on multiplication and division. | ||
4305 | 521 | self.autoconvert_offset_to_baseunit = autoconvert_offset_to_baseunit | ||
4306 | 497 | 522 | ||
4307 | 498 | if filename == '': | 523 | if filename == '': |
4308 | 499 | self.load_definitions('default_en.txt', True) | 524 | self.load_definitions('default_en.txt', True) |
4309 | @@ -504,6 +529,9 @@ | |||
4310 | 504 | 529 | ||
4311 | 505 | self._build_cache() | 530 | self._build_cache() |
4312 | 506 | 531 | ||
4313 | 532 | def __name__(self): | ||
4314 | 533 | return 'UnitRegistry' | ||
4315 | 534 | |||
4316 | 507 | def __getattr__(self, item): | 535 | def __getattr__(self, item): |
4317 | 508 | return self.Quantity(1, item) | 536 | return self.Quantity(1, item) |
4318 | 509 | 537 | ||
4319 | @@ -697,7 +725,8 @@ | |||
4320 | 697 | 725 | ||
4321 | 698 | _adder(alias, definition) | 726 | _adder(alias, definition) |
4322 | 699 | 727 | ||
4324 | 700 | if isinstance(definition.converter, OffsetConverter): | 728 | # define additional "delta_" units for units with an offset |
4325 | 729 | if getattr(definition.converter, "offset", 0.0) != 0.0: | ||
4326 | 701 | d_name = 'delta_' + definition.name | 730 | d_name = 'delta_' + definition.name |
4327 | 702 | if definition.symbol: | 731 | if definition.symbol: |
4328 | 703 | d_symbol = 'Δ' + definition.symbol | 732 | d_symbol = 'Δ' + definition.symbol |
4329 | @@ -710,7 +739,7 @@ | |||
4330 | 710 | return '[delta_' + _name[1:] | 739 | return '[delta_' + _name[1:] |
4331 | 711 | return 'delta_' + _name | 740 | return 'delta_' + _name |
4332 | 712 | 741 | ||
4334 | 713 | d_reference = UnitsContainer(dict((prep(ref), value) | 742 | d_reference = UnitsContainer(dict((ref, value) |
4335 | 714 | for ref, value in definition.reference.items())) | 743 | for ref, value in definition.reference.items())) |
4336 | 715 | 744 | ||
4337 | 716 | self.define(UnitDefinition(d_name, d_symbol, d_aliases, | 745 | self.define(UnitDefinition(d_name, d_symbol, d_aliases, |
4338 | @@ -818,7 +847,7 @@ | |||
4339 | 818 | return '' | 847 | return '' |
4340 | 819 | 848 | ||
4341 | 820 | try: | 849 | try: |
4343 | 821 | return self._units[name_or_alias].name | 850 | return self._units[name_or_alias]._name |
4344 | 822 | except KeyError: | 851 | except KeyError: |
4345 | 823 | pass | 852 | pass |
4346 | 824 | 853 | ||
4347 | @@ -857,15 +886,17 @@ | |||
4348 | 857 | 886 | ||
4349 | 858 | return self._prefixes[prefix].symbol + self._units[unit_name].symbol | 887 | return self._prefixes[prefix].symbol + self._units[unit_name].symbol |
4350 | 859 | 888 | ||
4351 | 889 | def _get_symbol(self, name): | ||
4352 | 890 | return self._units[name].symbol | ||
4353 | 891 | |||
4354 | 860 | def get_dimensionality(self, input_units): | 892 | def get_dimensionality(self, input_units): |
4355 | 861 | """Convert unit or dict of units or dimensions to a dict of base dimensions | 893 | """Convert unit or dict of units or dimensions to a dict of base dimensions |
4356 | 862 | 894 | ||
4357 | 863 | :param input_units: | 895 | :param input_units: |
4358 | 864 | :return: dimensionality | 896 | :return: dimensionality |
4359 | 865 | """ | 897 | """ |
4360 | 866 | dims = UnitsContainer() | ||
4361 | 867 | if not input_units: | 898 | if not input_units: |
4363 | 868 | return dims | 899 | return UnitsContainer() |
4364 | 869 | 900 | ||
4365 | 870 | if isinstance(input_units, string_types): | 901 | if isinstance(input_units, string_types): |
4366 | 871 | input_units = ParserHelper.from_string(input_units) | 902 | input_units = ParserHelper.from_string(input_units) |
4367 | @@ -873,24 +904,31 @@ | |||
4368 | 873 | if input_units in self._dimensionality_cache: | 904 | if input_units in self._dimensionality_cache: |
4369 | 874 | return copy.copy(self._dimensionality_cache[input_units]) | 905 | return copy.copy(self._dimensionality_cache[input_units]) |
4370 | 875 | 906 | ||
4372 | 876 | for key, value in input_units.items(): | 907 | accumulator = defaultdict(float) |
4373 | 908 | self._get_dimensionality_recurse(input_units, 1.0, accumulator) | ||
4374 | 909 | |||
4375 | 910 | dims = UnitsContainer(dict((k, v) for k, v in accumulator.items() if v != 0.)) | ||
4376 | 911 | |||
4377 | 912 | if '[]' in dims: | ||
4378 | 913 | del dims['[]'] | ||
4379 | 914 | |||
4380 | 915 | self._dimensionality_cache[input_units] = copy.copy(dims) | ||
4381 | 916 | |||
4382 | 917 | return dims | ||
4383 | 918 | |||
4384 | 919 | def _get_dimensionality_recurse(self, ref, exp, accumulator): | ||
4385 | 920 | for key in ref: | ||
4386 | 921 | exp2 = exp*ref[key] | ||
4387 | 877 | if _is_dim(key): | 922 | if _is_dim(key): |
4388 | 878 | reg = self._dimensions[key] | 923 | reg = self._dimensions[key] |
4389 | 879 | if reg.is_base: | 924 | if reg.is_base: |
4393 | 880 | dims.add(key, value) | 925 | accumulator[key] += exp2 |
4394 | 881 | else: | 926 | elif reg.reference is not None: |
4395 | 882 | dims *= self.get_dimensionality(reg.reference) ** value | 927 | self._get_dimensionality_recurse(reg.reference, exp2, accumulator) |
4396 | 883 | else: | 928 | else: |
4397 | 884 | reg = self._units[self.get_name(key)] | 929 | reg = self._units[self.get_name(key)] |
4407 | 885 | if reg.is_base: | 930 | if reg.reference is not None: |
4408 | 886 | dims *= reg.reference ** value | 931 | self._get_dimensionality_recurse(reg.reference, exp2, accumulator) |
4400 | 887 | else: | ||
4401 | 888 | dims *= self.get_dimensionality(reg.reference) ** value | ||
4402 | 889 | |||
4403 | 890 | if '[]' in dims: | ||
4404 | 891 | del dims['[]'] | ||
4405 | 892 | |||
4406 | 893 | return dims | ||
4409 | 894 | 932 | ||
4410 | 895 | def get_base_units(self, input_units, check_nonmult=True): | 933 | def get_base_units(self, input_units, check_nonmult=True): |
4411 | 896 | """Convert unit or dict of units to the base units. | 934 | """Convert unit or dict of units to the base units. |
4412 | @@ -914,27 +952,32 @@ | |||
4413 | 914 | if check_nonmult and input_units in self._base_units_cache: | 952 | if check_nonmult and input_units in self._base_units_cache: |
4414 | 915 | return copy.deepcopy(self._base_units_cache[input_units]) | 953 | return copy.deepcopy(self._base_units_cache[input_units]) |
4415 | 916 | 954 | ||
4428 | 917 | factor = 1. | 955 | accumulators = [1., defaultdict(float)] |
4429 | 918 | units = UnitsContainer() | 956 | self._get_base_units(input_units, 1.0, accumulators) |
4430 | 919 | for key, value in input_units.items(): | 957 | |
4431 | 920 | key = self.get_name(key) | 958 | factor = accumulators[0] |
4432 | 921 | reg = self._units[key] | 959 | units = UnitsContainer(dict((k, v) for k, v in accumulators[1].items() if v != 0.)) |
4421 | 922 | if reg.is_base: | ||
4422 | 923 | units.add(key, value) | ||
4423 | 924 | else: | ||
4424 | 925 | fac, uni = self.get_base_units(reg.reference, check_nonmult=False) | ||
4425 | 926 | if factor is not None: | ||
4426 | 927 | factor *= (reg.converter.scale * fac) ** value | ||
4427 | 928 | units *= uni ** value | ||
4433 | 929 | 960 | ||
4434 | 930 | # Check if any of the final units is non multiplicative and return None instead. | 961 | # Check if any of the final units is non multiplicative and return None instead. |
4435 | 931 | if check_nonmult: | 962 | if check_nonmult: |
4436 | 932 | for unit in units.keys(): | 963 | for unit in units.keys(): |
4438 | 933 | if not isinstance(self._units[unit].converter, ScaleConverter): | 964 | if not self._units[unit].converter.is_multiplicative: |
4439 | 934 | return None, units | 965 | return None, units |
4440 | 935 | 966 | ||
4441 | 936 | return factor, units | 967 | return factor, units |
4442 | 937 | 968 | ||
4443 | 969 | def _get_base_units(self, ref, exp, accumulators): | ||
4444 | 970 | for key in ref: | ||
4445 | 971 | exp2 = exp*ref[key] | ||
4446 | 972 | key = self.get_name(key) | ||
4447 | 973 | reg = self._units[key] | ||
4448 | 974 | if reg.is_base: | ||
4449 | 975 | accumulators[1][key] += exp2 | ||
4450 | 976 | else: | ||
4451 | 977 | accumulators[0] *= reg._converter.scale ** exp2 | ||
4452 | 978 | if reg.reference is not None: | ||
4453 | 979 | self._get_base_units(reg.reference, exp2, accumulators) | ||
4454 | 980 | |||
4455 | 938 | def get_compatible_units(self, input_units): | 981 | def get_compatible_units(self, input_units): |
4456 | 939 | if not input_units: | 982 | if not input_units: |
4457 | 940 | return 1., UnitsContainer() | 983 | return 1., UnitsContainer() |
4458 | @@ -967,9 +1010,9 @@ | |||
4459 | 967 | :return: converted value | 1010 | :return: converted value |
4460 | 968 | """ | 1011 | """ |
4461 | 969 | if isinstance(src, string_types): | 1012 | if isinstance(src, string_types): |
4463 | 970 | src = ParserHelper.from_string(src) | 1013 | src = self.parse_units(src) |
4464 | 971 | if isinstance(dst, string_types): | 1014 | if isinstance(dst, string_types): |
4466 | 972 | dst = ParserHelper.from_string(dst) | 1015 | dst = self.parse_units(dst) |
4467 | 973 | if src == dst: | 1016 | if src == dst: |
4468 | 974 | return value | 1017 | return value |
4469 | 975 | 1018 | ||
4470 | @@ -997,36 +1040,59 @@ | |||
4471 | 997 | if src_dim != dst_dim: | 1040 | if src_dim != dst_dim: |
4472 | 998 | raise DimensionalityError(src, dst, src_dim, dst_dim) | 1041 | raise DimensionalityError(src, dst, src_dim, dst_dim) |
4473 | 999 | 1042 | ||
4498 | 1000 | if len(src) == 1: | 1043 | # Conversion needs to consider if non-multiplicative (AKA offset |
4499 | 1001 | # If the source has a single element, it might be a non-multiplicative unit | 1044 | # units) are involved. Conversion is only possible if src and dst |
4500 | 1002 | # and therefore it is treated differently. | 1045 | # have at most one offset unit per dimension. |
4501 | 1003 | src_unit, src_value = list(src.items())[0] | 1046 | src_offset_units = [(u, e) for u, e in src.items() |
4502 | 1004 | src_unit = self._units[self.get_name(src_unit)] | 1047 | if not self._units[u].is_multiplicative] |
4503 | 1005 | 1048 | dst_offset_units = [(u, e) for u, e in dst.items() | |
4504 | 1006 | # We only continue if is a ScaleConverter, | 1049 | if not self._units[u].is_multiplicative] |
4505 | 1007 | # if not just exit to use the standard src / dst. | 1050 | |
4506 | 1008 | # TODO: This will fail and should not degK * meter / nanometer -> degC | 1051 | # For offset units we need to check if the conversion is allowed. |
4507 | 1009 | if not isinstance(src_unit.converter, ScaleConverter): | 1052 | if src_offset_units or dst_offset_units: |
4508 | 1010 | 1053 | ||
4509 | 1011 | if len(dst) > 1: | 1054 | # Validate that not more than one offset unit is present |
4510 | 1012 | # If the destination has more than one element, | 1055 | if len(src_offset_units) > 1 or len(dst_offset_units) > 1: |
4511 | 1013 | # then the conversion is not possible. | 1056 | raise DimensionalityError( |
4512 | 1014 | # TODO: This will fail and should not degC -> degK * meter / nanometer | 1057 | src, dst, src_dim, dst_dim, |
4513 | 1015 | raise DimensionalityError(src, dst, src_dim, dst_dim) | 1058 | extra_msg=' - more than one offset unit.') |
4514 | 1016 | 1059 | ||
4515 | 1017 | dst_unit, dst_value = list(dst.items())[0] | 1060 | # validate that offset unit is not used in multiplicative context |
4516 | 1018 | dst_unit = self._units[self.get_name(dst_unit)] | 1061 | if ((len(src_offset_units) == 1 and len(src) > 1) |
4517 | 1019 | if not type(src_unit.converter) is type(dst_unit.converter): | 1062 | or (len(dst_offset_units) == 1 and len(dst) > 1) |
4518 | 1020 | raise DimensionalityError(src, dst, src_dim, dst_dim) | 1063 | and not self.autoconvert_offset_to_baseunit): |
4519 | 1021 | 1064 | raise DimensionalityError( | |
4520 | 1022 | return dst_unit.converter.from_reference(src_unit.converter.to_reference(value, inplace), inplace) | 1065 | src, dst, src_dim, dst_dim, |
4521 | 1023 | 1066 | extra_msg=' - offset unit used in multiplicative context.') | |
4522 | 1067 | |||
4523 | 1068 | # Validate that order of offset unit is exactly one. | ||
4524 | 1069 | if src_offset_units: | ||
4525 | 1070 | if src_offset_units[0][1] != 1: | ||
4526 | 1071 | raise DimensionalityError( | ||
4527 | 1072 | src, dst, src_dim, dst_dim, | ||
4528 | 1073 | extra_msg=' - offset units in higher order.') | ||
4529 | 1074 | else: | ||
4530 | 1075 | if dst_offset_units[0][1] != 1: | ||
4531 | 1076 | raise DimensionalityError( | ||
4532 | 1077 | src, dst, src_dim, dst_dim, | ||
4533 | 1078 | extra_msg=' - offset units in higher order.') | ||
4534 | 1079 | |||
4535 | 1080 | # Here we convert only the offset quantities. Any remaining scaled | ||
4536 | 1081 | # quantities will be converted later. | ||
4537 | 1082 | |||
4538 | 1083 | # clean src from offset units by converting to reference | ||
4539 | 1084 | for u, e in src_offset_units: | ||
4540 | 1085 | value = self._units[u].converter.to_reference(value, inplace) | ||
4541 | 1086 | src.pop(u) | ||
4542 | 1087 | |||
4543 | 1088 | # clean dst units from offset units | ||
4544 | 1089 | for u, e in dst_offset_units: | ||
4545 | 1090 | dst.pop(u) | ||
4546 | 1091 | |||
4547 | 1092 | # Here src and dst have only multiplicative units left. Thus we can | ||
4548 | 1093 | # convert with a factor. | ||
4549 | 1024 | factor, units = self.get_base_units(src / dst) | 1094 | factor, units = self.get_base_units(src / dst) |
4550 | 1025 | 1095 | ||
4551 | 1026 | if factor is None: | ||
4552 | 1027 | raise DimensionalityError(src, dst, src_dim, dst_dim, | ||
4553 | 1028 | 'Non-multiplicative unit found.') | ||
4554 | 1029 | |||
4555 | 1030 | # factor is type float and if our magnitude is type Decimal then | 1096 | # factor is type float and if our magnitude is type Decimal then |
4556 | 1031 | # must first convert to Decimal before we can '*' the values | 1097 | # must first convert to Decimal before we can '*' the values |
4557 | 1032 | if isinstance(value, Decimal): | 1098 | if isinstance(value, Decimal): |
4558 | @@ -1037,6 +1103,16 @@ | |||
4559 | 1037 | else: | 1103 | else: |
4560 | 1038 | value = value * factor | 1104 | value = value * factor |
4561 | 1039 | 1105 | ||
4562 | 1106 | # Finally convert to offset units specified in destination | ||
4563 | 1107 | for u, e in dst_offset_units: | ||
4564 | 1108 | value = self._units[u].converter.from_reference(value, inplace) | ||
4565 | 1109 | # add back offset units to dst | ||
4566 | 1110 | dst[u] = e | ||
4567 | 1111 | |||
4568 | 1112 | # restore offset conversion of src units | ||
4569 | 1113 | for u, e in src_offset_units: | ||
4570 | 1114 | src[u] = e | ||
4571 | 1115 | |||
4572 | 1040 | return value | 1116 | return value |
4573 | 1041 | 1117 | ||
4574 | 1042 | def pi_theorem(self, quantities): | 1118 | def pi_theorem(self, quantities): |
4575 | @@ -1069,9 +1145,10 @@ | |||
4576 | 1069 | """Parse a unit to identify prefix, unit name and suffix | 1145 | """Parse a unit to identify prefix, unit name and suffix |
4577 | 1070 | by walking the list of prefix and suffix. | 1146 | by walking the list of prefix and suffix. |
4578 | 1071 | """ | 1147 | """ |
4582 | 1072 | 1148 | stw = unit_name.startswith | |
4583 | 1073 | for suffix, prefix in itertools.product(self._suffixes.keys(), self._prefixes.keys()): | 1149 | edw = unit_name.endswith |
4584 | 1074 | if unit_name.startswith(prefix) and unit_name.endswith(suffix): | 1150 | for suffix, prefix in itertools.product(self._suffixes, self._prefixes): |
4585 | 1151 | if stw(prefix) and edw(suffix): | ||
4586 | 1075 | name = unit_name[len(prefix):] | 1152 | name = unit_name[len(prefix):] |
4587 | 1076 | if suffix: | 1153 | if suffix: |
4588 | 1077 | name = name[:-len(suffix)] | 1154 | name = name[:-len(suffix)] |
4589 | @@ -1079,30 +1156,33 @@ | |||
4590 | 1079 | continue | 1156 | continue |
4591 | 1080 | if case_sensitive: | 1157 | if case_sensitive: |
4592 | 1081 | if name in self._units: | 1158 | if name in self._units: |
4595 | 1082 | yield (self._prefixes[prefix].name, | 1159 | yield (self._prefixes[prefix]._name, |
4596 | 1083 | self._units[name].name, | 1160 | self._units[name]._name, |
4597 | 1084 | self._suffixes[suffix]) | 1161 | self._suffixes[suffix]) |
4598 | 1085 | else: | 1162 | else: |
4599 | 1086 | for real_name in self._units_casei.get(name.lower(), ()): | 1163 | for real_name in self._units_casei.get(name.lower(), ()): |
4602 | 1087 | yield (self._prefixes[prefix].name, | 1164 | yield (self._prefixes[prefix]._name, |
4603 | 1088 | self._units[real_name].name, | 1165 | self._units[real_name]._name, |
4604 | 1089 | self._suffixes[suffix]) | 1166 | self._suffixes[suffix]) |
4605 | 1090 | 1167 | ||
4607 | 1091 | def parse_units(self, input_string, to_delta=None): | 1168 | def parse_units(self, input_string, as_delta=None): |
4608 | 1092 | """Parse a units expression and returns a UnitContainer with | 1169 | """Parse a units expression and returns a UnitContainer with |
4609 | 1093 | the canonical names. | 1170 | the canonical names. |
4610 | 1094 | 1171 | ||
4611 | 1095 | The expression can only contain products, ratios and powers of units. | 1172 | The expression can only contain products, ratios and powers of units. |
4612 | 1096 | 1173 | ||
4614 | 1097 | :param to_delta: if the expression has multiple units, the parser will | 1174 | :param as_delta: if the expression has multiple units, the parser will |
4615 | 1098 | interpret non multiplicative units as their `delta_` counterparts. | 1175 | interpret non multiplicative units as their `delta_` counterparts. |
4616 | 1099 | 1176 | ||
4617 | 1100 | :raises: | 1177 | :raises: |
4618 | 1101 | :class:`pint.UndefinedUnitError` if a unit is not in the registry | 1178 | :class:`pint.UndefinedUnitError` if a unit is not in the registry |
4619 | 1102 | :class:`ValueError` if the expression is invalid. | 1179 | :class:`ValueError` if the expression is invalid. |
4620 | 1103 | """ | 1180 | """ |
4623 | 1104 | if to_delta is None: | 1181 | if input_string in self._parse_unit_cache: |
4624 | 1105 | to_delta = self.default_to_delta | 1182 | return self._parse_unit_cache[input_string] |
4625 | 1183 | |||
4626 | 1184 | if as_delta is None: | ||
4627 | 1185 | as_delta = self.default_as_delta | ||
4628 | 1106 | 1186 | ||
4629 | 1107 | if not input_string: | 1187 | if not input_string: |
4630 | 1108 | return UnitsContainer() | 1188 | return UnitsContainer() |
4631 | @@ -1113,16 +1193,19 @@ | |||
4632 | 1113 | 1193 | ||
4633 | 1114 | ret = UnitsContainer() | 1194 | ret = UnitsContainer() |
4634 | 1115 | many = len(units) > 1 | 1195 | many = len(units) > 1 |
4636 | 1116 | for name, value in units.items(): | 1196 | for name in units: |
4637 | 1117 | cname = self.get_name(name) | 1197 | cname = self.get_name(name) |
4638 | 1198 | value = units[name] | ||
4639 | 1118 | if not cname: | 1199 | if not cname: |
4640 | 1119 | continue | 1200 | continue |
4642 | 1120 | if to_delta and (many or (not many and abs(value) != 1)): | 1201 | if as_delta and (many or (not many and value != 1)): |
4643 | 1121 | definition = self._units[cname] | 1202 | definition = self._units[cname] |
4644 | 1122 | if not definition.is_multiplicative: | 1203 | if not definition.is_multiplicative: |
4645 | 1123 | cname = 'delta_' + cname | 1204 | cname = 'delta_' + cname |
4646 | 1124 | ret[cname] = value | 1205 | ret[cname] = value |
4647 | 1125 | 1206 | ||
4648 | 1207 | self._parse_unit_cache[input_string] = ret | ||
4649 | 1208 | |||
4650 | 1126 | return ret | 1209 | return ret |
4651 | 1127 | 1210 | ||
4652 | 1128 | def parse_expression(self, input_string, case_sensitive=True, **values): | 1211 | def parse_expression(self, input_string, case_sensitive=True, **values): |
4653 | @@ -1141,7 +1224,7 @@ | |||
4654 | 1141 | unknown = set() | 1224 | unknown = set() |
4655 | 1142 | for toknum, tokval, _, _, _ in gen: | 1225 | for toknum, tokval, _, _, _ in gen: |
4656 | 1143 | if toknum == NAME: | 1226 | if toknum == NAME: |
4658 | 1144 | # TODO: Integrate math better, Replace eval | 1227 | # TODO: Integrate math better, Replace eval, make as_delta-aware |
4659 | 1145 | if tokval == 'pi' or tokval in values: | 1228 | if tokval == 'pi' or tokval in values: |
4660 | 1146 | result.append((toknum, tokval)) | 1229 | result.append((toknum, tokval)) |
4661 | 1147 | continue | 1230 | continue |
4662 | 1148 | 1231 | ||
4663 | === modified file 'setup.cfg' | |||
4664 | --- setup.cfg 2014-09-05 23:26:05 +0000 | |||
4665 | +++ setup.cfg 2015-01-07 15:51:38 +0000 | |||
4666 | @@ -1,7 +1,13 @@ | |||
4667 | 1 | [check-manifest] | 1 | [check-manifest] |
4671 | 2 | ignore = | 2 | ignore = |
4672 | 3 | .travis.yml | 3 | .travis.yml |
4673 | 4 | tox.ini | 4 | tox.ini |
4674 | 5 | 5 | ||
4675 | 6 | [bdist_wheel] | 6 | [bdist_wheel] |
4676 | 7 | universal = 1 | 7 | universal = 1 |
4677 | 8 | |||
4678 | 9 | [egg_info] | ||
4679 | 10 | tag_build = | ||
4680 | 11 | tag_date = 0 | ||
4681 | 12 | tag_svn_revision = 0 | ||
4682 | 13 | |||
4683 | 8 | 14 | ||
4684 | === modified file 'setup.py' | |||
4685 | --- setup.py 2014-09-05 23:26:05 +0000 | |||
4686 | +++ setup.py 2015-01-07 15:51:38 +0000 | |||
4687 | @@ -29,7 +29,7 @@ | |||
4688 | 29 | 29 | ||
4689 | 30 | setup( | 30 | setup( |
4690 | 31 | name='Pint', | 31 | name='Pint', |
4692 | 32 | version='0.5.2', | 32 | version='0.6', |
4693 | 33 | description='Physical quantities module', | 33 | description='Physical quantities module', |
4694 | 34 | long_description=long_description, | 34 | long_description=long_description, |
4695 | 35 | keywords='physical quantities unit conversion science', | 35 | keywords='physical quantities unit conversion science', |
4696 | 36 | 36 | ||
4697 | === removed file 'tox.ini' | |||
4698 | --- tox.ini 2014-09-05 23:26:05 +0000 | |||
4699 | +++ tox.ini 1970-01-01 00:00:00 +0000 | |||
4700 | @@ -1,77 +0,0 @@ | |||
4701 | 1 | [tox] | ||
4702 | 2 | envlist = py26,py27,py32,py33,numpy26,numpy27,numpy32,numpy33, | ||
4703 | 3 | py26u,py27u,py32u,py33u,numpy26u,numpy27u,numpy32u,numpy33u | ||
4704 | 4 | |||
4705 | 5 | [testenv] | ||
4706 | 6 | deps = coverage | ||
4707 | 7 | commands = coverage run -p --source=pint setup.py test | ||
4708 | 8 | |||
4709 | 9 | setenv= | ||
4710 | 10 | COVERAGE_FILE=.coverage.{envname} | ||
4711 | 11 | |||
4712 | 12 | |||
4713 | 13 | [testenv:py26] | ||
4714 | 14 | deps = unittest2 | ||
4715 | 15 | coverage | ||
4716 | 16 | |||
4717 | 17 | [testenv:numpy26] | ||
4718 | 18 | deps = numpy | ||
4719 | 19 | unittest2 | ||
4720 | 20 | coverage | ||
4721 | 21 | |||
4722 | 22 | [testenv:numpy27] | ||
4723 | 23 | basepython=python2.7 | ||
4724 | 24 | deps = numpy | ||
4725 | 25 | coverage | ||
4726 | 26 | |||
4727 | 27 | [testenv:numpy32] | ||
4728 | 28 | basepython=python3.2 | ||
4729 | 29 | deps = numpy | ||
4730 | 30 | coverage | ||
4731 | 31 | |||
4732 | 32 | [testenv:numpy33] | ||
4733 | 33 | basepython=python3.3 | ||
4734 | 34 | deps = numpy | ||
4735 | 35 | coverage | ||
4736 | 36 | |||
4737 | 37 | |||
4738 | 38 | [testenv:py26u] | ||
4739 | 39 | deps = unittest2 | ||
4740 | 40 | uncertainties | ||
4741 | 41 | coverage | ||
4742 | 42 | |||
4743 | 43 | [testenv:py27u] | ||
4744 | 44 | deps = uncertainties | ||
4745 | 45 | coverage | ||
4746 | 46 | |||
4747 | 47 | [testenv:py32u] | ||
4748 | 48 | deps = uncertainties | ||
4749 | 49 | coverage | ||
4750 | 50 | |||
4751 | 51 | [testenv:py33u] | ||
4752 | 52 | deps = uncertainties | ||
4753 | 53 | coverage | ||
4754 | 54 | |||
4755 | 55 | [testenv:numpy26u] | ||
4756 | 56 | deps = numpy | ||
4757 | 57 | unittest2 | ||
4758 | 58 | uncertainties | ||
4759 | 59 | coverage | ||
4760 | 60 | |||
4761 | 61 | [testenv:numpy27u] | ||
4762 | 62 | basepython=python2.7 | ||
4763 | 63 | deps = numpy | ||
4764 | 64 | uncertainties | ||
4765 | 65 | coverage | ||
4766 | 66 | |||
4767 | 67 | [testenv:numpy32u] | ||
4768 | 68 | basepython=python3.2 | ||
4769 | 69 | deps = numpy | ||
4770 | 70 | uncertainties | ||
4771 | 71 | coverage | ||
4772 | 72 | |||
4773 | 73 | [testenv:numpy33u] | ||
4774 | 74 | basepython=python3.3 | ||
4775 | 75 | deps = numpy | ||
4776 | 76 | uncertainties | ||
4777 | 77 | coverage |
This already got uploaded without closing this MP: https:/ /launchpad. net/ubuntu/ +source/ python- pint/0. 6-0ubuntu1