qubasic 0.6.5__tar.gz → 0.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. {qubasic-0.6.5 → qubasic-0.8.0}/CHANGELOG.md +19 -0
  2. {qubasic-0.6.5/qubasic.egg-info → qubasic-0.8.0}/PKG-INFO +84 -1
  3. {qubasic-0.6.5 → qubasic-0.8.0}/README.md +83 -0
  4. {qubasic-0.6.5 → qubasic-0.8.0}/pyproject.toml +1 -1
  5. {qubasic-0.6.5 → qubasic-0.8.0/qubasic.egg-info}/PKG-INFO +84 -1
  6. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic.egg-info/SOURCES.txt +1 -0
  7. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/__init__.py +1 -1
  8. qubasic-0.8.0/qubasic_core/algorithms.py +428 -0
  9. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/analysis.py +252 -0
  10. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/engine_state.py +1 -0
  11. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/executor.py +68 -0
  12. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/file_io.py +157 -1
  13. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/parser.py +5 -0
  14. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/qol.py +3 -0
  15. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/statements.py +1 -1
  16. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/terminal.py +184 -14
  17. {qubasic-0.6.5 → qubasic-0.8.0}/tests/test_qubasic.py +178 -7
  18. {qubasic-0.6.5 → qubasic-0.8.0}/LICENSE +0 -0
  19. {qubasic-0.6.5 → qubasic-0.8.0}/MANIFEST.in +0 -0
  20. {qubasic-0.6.5 → qubasic-0.8.0}/examples/bell.qb +0 -0
  21. {qubasic-0.6.5 → qubasic-0.8.0}/examples/grover3.qb +0 -0
  22. {qubasic-0.6.5 → qubasic-0.8.0}/examples/locc_teleport.qb +0 -0
  23. {qubasic-0.6.5 → qubasic-0.8.0}/examples/sweep_rx.qb +0 -0
  24. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic.egg-info/dependency_links.txt +0 -0
  25. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic.egg-info/entry_points.txt +0 -0
  26. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic.egg-info/requires.txt +0 -0
  27. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic.egg-info/top_level.txt +0 -0
  28. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/__main__.py +0 -0
  29. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/backend.py +0 -0
  30. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/classic.py +0 -0
  31. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/cli.py +0 -0
  32. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/control_flow.py +0 -0
  33. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/debug.py +0 -0
  34. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/demos.py +0 -0
  35. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/display.py +0 -0
  36. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/engine.py +0 -0
  37. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/errors.py +0 -0
  38. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/exec_context.py +0 -0
  39. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/expression.py +0 -0
  40. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/gates.py +0 -0
  41. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/help_text.py +0 -0
  42. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/io_protocol.py +0 -0
  43. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/locc.py +0 -0
  44. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/locc_commands.py +0 -0
  45. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/locc_display.py +0 -0
  46. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/locc_engine.py +0 -0
  47. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/locc_execution.py +0 -0
  48. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/memory.py +0 -0
  49. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/mock_backend.py +0 -0
  50. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/noise_mixin.py +0 -0
  51. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/patterns.py +0 -0
  52. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/profiler.py +0 -0
  53. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/program_mgmt.py +0 -0
  54. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/protocol.py +0 -0
  55. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/scope.py +0 -0
  56. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/screen.py +0 -0
  57. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/state_display.py +0 -0
  58. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/strings.py +0 -0
  59. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/subs.py +0 -0
  60. {qubasic-0.6.5 → qubasic-0.8.0}/qubasic_core/sweep.py +0 -0
  61. {qubasic-0.6.5 → qubasic-0.8.0}/setup.cfg +0 -0
  62. {qubasic-0.6.5 → qubasic-0.8.0}/tests/test_features.py +0 -0
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0 (2026-06-19)
4
+
5
+ ### Added
6
+ - Partial measurement: `MEASURE 0, 2` measures a subset of qubits and reports the histogram over just those qubits (the bare `MEASURE` still measures all).
7
+ - Process tomography: `PTOMOGRAPHY` reconstructs the circuit's Pauli Transfer Matrix (the unitary, or the full noisy channel via the superoperator when a noise model is active), and reports the trace-preserving and unital flags plus the average gate fidelity to the identity. Limited to <= 2 qubits.
8
+ - Randomized benchmarking: `RB [max_length] [samples]` runs single-qubit RB over the 24-element Clifford group (each sequence ends with its recovery Clifford), fits the survival decay `p(m) = A f^m + B`, and reports the decay `f` and the error per Clifford `(1 - f)/2`. Reflects the active noise model.
9
+
10
+ ## 0.7.0 (2026-06-19)
11
+
12
+ ### Added
13
+ - Dynamic circuits in the standard Aer path: `MEAS q -> c` is a real mid-circuit measurement and `IF c THEN <gate>` (also `IF c == 0`, `NOT c`, and `ELSE`) compiles to a Qiskit `if_test`, so feedforward corrections run on the actual outcome without LOCC mode. The mid-circuit measurement registers are kept out of the reported histogram.
14
+ - Algorithm primitives applied to a qubit range: `QFT`/`IQFT`, `DIFFUSE` (Grover diffusion), `MCX`/`MCZ`/`MCP` (arbitrary control count), `QADD`/`QADDC` (in-place register and constant addition mod 2^n), and `QPE` (phase estimation of a UNITARY). The QFT is least-significant-first (qubit 0 = low bit) so register reads are consistent.
15
+ - Optimization drivers: `MINIMIZE v1, v2 -> <cost expr>` runs a dependency-free Nelder-Mead optimizer over circuit parameters (VQE/QAOA), and `GRADIENT` computes the parameter-shift gradient. The cost is any expression evaluated after each run from variables the program sets (for example via `SAVE_EXPECT`).
16
+ - Device model for transpilation: `COUPLING linear|ring|full|<edges>` constrains two-qubit connectivity and `BASIS <gates>` restricts to a native gate set, both offline; RUN reports the routed depth and SWAP count.
17
+ - `FIDELITY <target>` (state fidelity against a named state or amplitude list) and `TOMOGRAPHY [shots]` (density-matrix reconstruction from Pauli expectations, exact or shot-sampled).
18
+ - `LOADQASM <file>` imports OpenQASM as an editable program (2.0 built-in; 3.0 requires the optional `qiskit_qasm3_import` package).
19
+ - `SET_DENSITY [[...]]` injects a mixed state (density matrix) for the next run, using the density_matrix method.
20
+ - `SAVEPNG <file> hist|bloch|circuit` saves a plot as a PNG (requires matplotlib; circuit diagrams also need pylatexenc).
21
+
3
22
  ## 0.6.5 (2026-06-19)
4
23
 
5
24
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qubasic
3
- Version: 0.6.5
3
+ Version: 0.8.0
4
4
  Summary: Quantum BASIC Interactive Terminal
5
5
  Author-email: "Charles C. Norton" <machineelv@gmail.com>
6
6
  License-Expression: MIT
@@ -417,6 +417,89 @@ STATS SHOW Show mean/stddev/min/max per state
417
417
  STATS CLEAR Reset accumulator
418
418
  ```
419
419
 
420
+ ### Characterization
421
+ ```
422
+ FIDELITY |BELL> State fidelity |<target|psi>|^2 vs a named state
423
+ FIDELITY [0.707,0,0,0.707] ...or an explicit amplitude list
424
+ TOMOGRAPHY State tomography: reconstruct rho from Pauli expectations
425
+ TOMOGRAPHY 2000 Statistical tomography (2000 shots per Pauli basis)
426
+ PTOMOGRAPHY Process tomography: reconstruct the Pauli Transfer Matrix (<=2 qubits)
427
+ RB Single-qubit randomized benchmarking (fits decay -> error/Clifford)
428
+ RB 64 12 Sequence lengths up to 64, 12 random sequences each
429
+ ```
430
+
431
+ ### Partial measurement
432
+ ```
433
+ MEASURE Measure all qubits (the default)
434
+ MEASURE 0, 2 Measure only qubits 0 and 2; histogram is over that subset
435
+ ```
436
+
437
+ ## Algorithm primitives
438
+
439
+ Composable building blocks applied to a qubit range (`lo-hi`, a list, or all
440
+ qubits). Qiskit-path only.
441
+
442
+ ```
443
+ QFT 0-3 Quantum Fourier transform over qubits 0..3
444
+ IQFT 0-3 Inverse QFT
445
+ DIFFUSE 0-2 Grover diffusion operator (2|s><s| - I)
446
+ MCX 0,1,2, 3 Multi-controlled X (any number of controls, last = target)
447
+ MCZ 0,1,2 Multi-controlled Z
448
+ MCP theta, 0,1, 2 Multi-controlled phase
449
+ QADD 0-2, 3-5 In-place register add: A += B (mod 2^n), qubit 0 = LSB
450
+ QADDC 5, 0-2 In-place constant add: A += 5 (mod 2^n)
451
+ QPE 0-3 4 UGATE Phase estimation of a UNITARY on a target register
452
+ ```
453
+
454
+ ## Optimization
455
+
456
+ Classical drivers over circuit parameters (VQE/QAOA). Build a parametrized
457
+ ansatz, compute a cost with `SAVE_EXPECT`, then minimize it.
458
+
459
+ ```
460
+ 10 RY theta, 0
461
+ 20 SAVE_EXPECT Z 0 -> cost
462
+ MINIMIZE theta -> cost Nelder-Mead minimization (dependency-free)
463
+ MINIMIZE a, b -> z0 + 0.5*z1 ITERS 200 Multi-parameter; cost is any post-run expression
464
+ GRADIENT theta -> cost Parameter-shift gradient d(cost)/d(theta)
465
+ ```
466
+
467
+ ## Dynamic circuits (feedforward)
468
+
469
+ In standard mode, `MEAS` is a real mid-circuit measurement and `IF` on the
470
+ measured bit compiles to a Qiskit `if_test`, so the conditional gate runs at
471
+ simulation time based on the actual outcome (no LOCC mode needed).
472
+
473
+ ```
474
+ 10 H 0
475
+ 20 MEAS 0 -> c Mid-circuit measurement into classical bit c
476
+ 30 IF c THEN X 0 Feedforward correction (also: IF c == 0, NOT c, with ELSE)
477
+ 40 MEASURE
478
+ ```
479
+
480
+ ## Mixed states
481
+
482
+ ```
483
+ SET_DENSITY [[0.5,0],[0,0.5]] Inject a density matrix (uses density_matrix method)
484
+ ```
485
+
486
+ ## Device model
487
+
488
+ Constrain transpilation to a hardware topology and native gate set, fully
489
+ offline. After RUN, the routed depth and SWAP count are reported.
490
+
491
+ ```
492
+ COUPLING linear 1D chain connectivity (also: ring, full, OFF, or 0-1, 1-2, ...)
493
+ BASIS rz, sx, x, cx Restrict to a native gate set (BASIS OFF to clear)
494
+ ```
495
+
496
+ ## Import and images
497
+
498
+ ```
499
+ LOADQASM file.qasm Import OpenQASM as an editable program (2.0 built-in; 3.0 needs qiskit_qasm3_import)
500
+ SAVEPNG out.png hist Save the histogram as a PNG (also: bloch, circuit; needs matplotlib)
501
+ ```
502
+
420
503
  ## Noise models
421
504
 
422
505
  ```
@@ -384,6 +384,89 @@ STATS SHOW Show mean/stddev/min/max per state
384
384
  STATS CLEAR Reset accumulator
385
385
  ```
386
386
 
387
+ ### Characterization
388
+ ```
389
+ FIDELITY |BELL> State fidelity |<target|psi>|^2 vs a named state
390
+ FIDELITY [0.707,0,0,0.707] ...or an explicit amplitude list
391
+ TOMOGRAPHY State tomography: reconstruct rho from Pauli expectations
392
+ TOMOGRAPHY 2000 Statistical tomography (2000 shots per Pauli basis)
393
+ PTOMOGRAPHY Process tomography: reconstruct the Pauli Transfer Matrix (<=2 qubits)
394
+ RB Single-qubit randomized benchmarking (fits decay -> error/Clifford)
395
+ RB 64 12 Sequence lengths up to 64, 12 random sequences each
396
+ ```
397
+
398
+ ### Partial measurement
399
+ ```
400
+ MEASURE Measure all qubits (the default)
401
+ MEASURE 0, 2 Measure only qubits 0 and 2; histogram is over that subset
402
+ ```
403
+
404
+ ## Algorithm primitives
405
+
406
+ Composable building blocks applied to a qubit range (`lo-hi`, a list, or all
407
+ qubits). Qiskit-path only.
408
+
409
+ ```
410
+ QFT 0-3 Quantum Fourier transform over qubits 0..3
411
+ IQFT 0-3 Inverse QFT
412
+ DIFFUSE 0-2 Grover diffusion operator (2|s><s| - I)
413
+ MCX 0,1,2, 3 Multi-controlled X (any number of controls, last = target)
414
+ MCZ 0,1,2 Multi-controlled Z
415
+ MCP theta, 0,1, 2 Multi-controlled phase
416
+ QADD 0-2, 3-5 In-place register add: A += B (mod 2^n), qubit 0 = LSB
417
+ QADDC 5, 0-2 In-place constant add: A += 5 (mod 2^n)
418
+ QPE 0-3 4 UGATE Phase estimation of a UNITARY on a target register
419
+ ```
420
+
421
+ ## Optimization
422
+
423
+ Classical drivers over circuit parameters (VQE/QAOA). Build a parametrized
424
+ ansatz, compute a cost with `SAVE_EXPECT`, then minimize it.
425
+
426
+ ```
427
+ 10 RY theta, 0
428
+ 20 SAVE_EXPECT Z 0 -> cost
429
+ MINIMIZE theta -> cost Nelder-Mead minimization (dependency-free)
430
+ MINIMIZE a, b -> z0 + 0.5*z1 ITERS 200 Multi-parameter; cost is any post-run expression
431
+ GRADIENT theta -> cost Parameter-shift gradient d(cost)/d(theta)
432
+ ```
433
+
434
+ ## Dynamic circuits (feedforward)
435
+
436
+ In standard mode, `MEAS` is a real mid-circuit measurement and `IF` on the
437
+ measured bit compiles to a Qiskit `if_test`, so the conditional gate runs at
438
+ simulation time based on the actual outcome (no LOCC mode needed).
439
+
440
+ ```
441
+ 10 H 0
442
+ 20 MEAS 0 -> c Mid-circuit measurement into classical bit c
443
+ 30 IF c THEN X 0 Feedforward correction (also: IF c == 0, NOT c, with ELSE)
444
+ 40 MEASURE
445
+ ```
446
+
447
+ ## Mixed states
448
+
449
+ ```
450
+ SET_DENSITY [[0.5,0],[0,0.5]] Inject a density matrix (uses density_matrix method)
451
+ ```
452
+
453
+ ## Device model
454
+
455
+ Constrain transpilation to a hardware topology and native gate set, fully
456
+ offline. After RUN, the routed depth and SWAP count are reported.
457
+
458
+ ```
459
+ COUPLING linear 1D chain connectivity (also: ring, full, OFF, or 0-1, 1-2, ...)
460
+ BASIS rz, sx, x, cx Restrict to a native gate set (BASIS OFF to clear)
461
+ ```
462
+
463
+ ## Import and images
464
+
465
+ ```
466
+ LOADQASM file.qasm Import OpenQASM as an editable program (2.0 built-in; 3.0 needs qiskit_qasm3_import)
467
+ SAVEPNG out.png hist Save the histogram as a PNG (also: bloch, circuit; needs matplotlib)
468
+ ```
469
+
387
470
  ## Noise models
388
471
 
389
472
  ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "qubasic"
7
- version = "0.6.5"
7
+ version = "0.8.0"
8
8
  description = "Quantum BASIC Interactive Terminal"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qubasic
3
- Version: 0.6.5
3
+ Version: 0.8.0
4
4
  Summary: Quantum BASIC Interactive Terminal
5
5
  Author-email: "Charles C. Norton" <machineelv@gmail.com>
6
6
  License-Expression: MIT
@@ -417,6 +417,89 @@ STATS SHOW Show mean/stddev/min/max per state
417
417
  STATS CLEAR Reset accumulator
418
418
  ```
419
419
 
420
+ ### Characterization
421
+ ```
422
+ FIDELITY |BELL> State fidelity |<target|psi>|^2 vs a named state
423
+ FIDELITY [0.707,0,0,0.707] ...or an explicit amplitude list
424
+ TOMOGRAPHY State tomography: reconstruct rho from Pauli expectations
425
+ TOMOGRAPHY 2000 Statistical tomography (2000 shots per Pauli basis)
426
+ PTOMOGRAPHY Process tomography: reconstruct the Pauli Transfer Matrix (<=2 qubits)
427
+ RB Single-qubit randomized benchmarking (fits decay -> error/Clifford)
428
+ RB 64 12 Sequence lengths up to 64, 12 random sequences each
429
+ ```
430
+
431
+ ### Partial measurement
432
+ ```
433
+ MEASURE Measure all qubits (the default)
434
+ MEASURE 0, 2 Measure only qubits 0 and 2; histogram is over that subset
435
+ ```
436
+
437
+ ## Algorithm primitives
438
+
439
+ Composable building blocks applied to a qubit range (`lo-hi`, a list, or all
440
+ qubits). Qiskit-path only.
441
+
442
+ ```
443
+ QFT 0-3 Quantum Fourier transform over qubits 0..3
444
+ IQFT 0-3 Inverse QFT
445
+ DIFFUSE 0-2 Grover diffusion operator (2|s><s| - I)
446
+ MCX 0,1,2, 3 Multi-controlled X (any number of controls, last = target)
447
+ MCZ 0,1,2 Multi-controlled Z
448
+ MCP theta, 0,1, 2 Multi-controlled phase
449
+ QADD 0-2, 3-5 In-place register add: A += B (mod 2^n), qubit 0 = LSB
450
+ QADDC 5, 0-2 In-place constant add: A += 5 (mod 2^n)
451
+ QPE 0-3 4 UGATE Phase estimation of a UNITARY on a target register
452
+ ```
453
+
454
+ ## Optimization
455
+
456
+ Classical drivers over circuit parameters (VQE/QAOA). Build a parametrized
457
+ ansatz, compute a cost with `SAVE_EXPECT`, then minimize it.
458
+
459
+ ```
460
+ 10 RY theta, 0
461
+ 20 SAVE_EXPECT Z 0 -> cost
462
+ MINIMIZE theta -> cost Nelder-Mead minimization (dependency-free)
463
+ MINIMIZE a, b -> z0 + 0.5*z1 ITERS 200 Multi-parameter; cost is any post-run expression
464
+ GRADIENT theta -> cost Parameter-shift gradient d(cost)/d(theta)
465
+ ```
466
+
467
+ ## Dynamic circuits (feedforward)
468
+
469
+ In standard mode, `MEAS` is a real mid-circuit measurement and `IF` on the
470
+ measured bit compiles to a Qiskit `if_test`, so the conditional gate runs at
471
+ simulation time based on the actual outcome (no LOCC mode needed).
472
+
473
+ ```
474
+ 10 H 0
475
+ 20 MEAS 0 -> c Mid-circuit measurement into classical bit c
476
+ 30 IF c THEN X 0 Feedforward correction (also: IF c == 0, NOT c, with ELSE)
477
+ 40 MEASURE
478
+ ```
479
+
480
+ ## Mixed states
481
+
482
+ ```
483
+ SET_DENSITY [[0.5,0],[0,0.5]] Inject a density matrix (uses density_matrix method)
484
+ ```
485
+
486
+ ## Device model
487
+
488
+ Constrain transpilation to a hardware topology and native gate set, fully
489
+ offline. After RUN, the routed depth and SWAP count are reported.
490
+
491
+ ```
492
+ COUPLING linear 1D chain connectivity (also: ring, full, OFF, or 0-1, 1-2, ...)
493
+ BASIS rz, sx, x, cx Restrict to a native gate set (BASIS OFF to clear)
494
+ ```
495
+
496
+ ## Import and images
497
+
498
+ ```
499
+ LOADQASM file.qasm Import OpenQASM as an editable program (2.0 built-in; 3.0 needs qiskit_qasm3_import)
500
+ SAVEPNG out.png hist Save the histogram as a PNG (also: bloch, circuit; needs matplotlib)
501
+ ```
502
+
420
503
  ## Noise models
421
504
 
422
505
  ```
@@ -15,6 +15,7 @@ qubasic.egg-info/requires.txt
15
15
  qubasic.egg-info/top_level.txt
16
16
  qubasic_core/__init__.py
17
17
  qubasic_core/__main__.py
18
+ qubasic_core/algorithms.py
18
19
  qubasic_core/analysis.py
19
20
  qubasic_core/backend.py
20
21
  qubasic_core/classic.py
@@ -28,7 +28,7 @@ __all__ = [
28
28
  'GATE_TABLE', 'GATE_ALIASES',
29
29
  ]
30
30
 
31
- __version__ = '0.6.5'
31
+ __version__ = '0.8.0'
32
32
 
33
33
  def __getattr__(name):
34
34
  """Lazy import heavy modules on first access."""