Showing preview only (5,554K chars total). Download the full file or copy to clipboard to get everything.
Repository: bloomberg/memray
Branch: main
Commit: 87e7f6205833
Files: 399
Total size: 5.2 MB
Directory structure:
gitextract_sf0scbj0/
├── .babelrc
├── .bumpversion.cfg
├── .clang-format
├── .devcontainer/
│ ├── devcontainer.json
│ └── tutorials/
│ └── devcontainer.json
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── ---bug-report.yaml
│ │ ├── ---feature-request.yaml
│ │ └── config.yml
│ ├── dependabot.yml
│ └── workflows/
│ ├── build.yml
│ ├── build_wheels.yml
│ ├── coverage.yml
│ ├── docs.yml
│ ├── news-check.yml
│ ├── sanity-check.yml
│ └── test_uv_python.yml
├── .gitignore
├── .pre-commit-config.yaml
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── MANIFEST.in
├── NEWS.rst
├── README.md
├── asv.conf.json
├── benchmarks/
│ ├── __init__.py
│ ├── benchmarking/
│ │ ├── __main__.py
│ │ ├── cases/
│ │ │ ├── __init__.py
│ │ │ ├── async_tree_base.py
│ │ │ ├── async_tree_memray.py
│ │ │ ├── deltablue_base.py
│ │ │ ├── deltablue_memray.py
│ │ │ ├── docutils_data/
│ │ │ │ └── docs/
│ │ │ │ ├── api/
│ │ │ │ │ ├── publisher.txt
│ │ │ │ │ ├── runtime-settings.txt
│ │ │ │ │ └── transforms.txt
│ │ │ │ ├── dev/
│ │ │ │ │ ├── distributing.txt
│ │ │ │ │ ├── enthought-plan.txt
│ │ │ │ │ ├── enthought-rfp.txt
│ │ │ │ │ ├── hacking.txt
│ │ │ │ │ ├── policies.txt
│ │ │ │ │ ├── pysource.txt
│ │ │ │ │ ├── release.txt
│ │ │ │ │ ├── repository.txt
│ │ │ │ │ ├── rst/
│ │ │ │ │ │ ├── alternatives.txt
│ │ │ │ │ │ └── problems.txt
│ │ │ │ │ ├── runtime-settings-processing.txt
│ │ │ │ │ ├── semantics.txt
│ │ │ │ │ ├── testing.txt
│ │ │ │ │ ├── todo.txt
│ │ │ │ │ └── website.txt
│ │ │ │ └── index.txt
│ │ │ ├── docutils_html_base.py
│ │ │ ├── docutils_html_memray.py
│ │ │ ├── fannkuch_base.py
│ │ │ ├── fannkuch_memray.py
│ │ │ ├── go_base.py
│ │ │ ├── go_memray.py
│ │ │ ├── hexion_base.py
│ │ │ ├── hexion_memray.py
│ │ │ ├── json_dumps_base.py
│ │ │ ├── json_dumps_memray.py
│ │ │ ├── json_loads_base.py
│ │ │ ├── json_loads_memray.py
│ │ │ ├── mdp_base.py
│ │ │ ├── mdp_memray.py
│ │ │ ├── meteor_context_base.py
│ │ │ ├── meteor_context_memray.py
│ │ │ ├── nbody_base.py
│ │ │ ├── nbody_memray.py
│ │ │ ├── nqueens_base.py
│ │ │ ├── nqueens_memray.py
│ │ │ ├── pickles_base.py
│ │ │ ├── pickles_memray.py
│ │ │ ├── pprint_format_base.py
│ │ │ ├── pprint_format_memray.py
│ │ │ ├── raytrace_base.py
│ │ │ ├── raytrace_memray.py
│ │ │ ├── regex_dna_base.py
│ │ │ ├── regex_dna_memray.py
│ │ │ ├── regex_effbot_base.py
│ │ │ ├── regex_effbot_memray.py
│ │ │ ├── regex_v8_base.py
│ │ │ ├── regex_v8_memray.py
│ │ │ ├── spectral_norm_base.py
│ │ │ ├── spectral_norm_memray.py
│ │ │ ├── sqlite_synth_base.py
│ │ │ ├── sqlite_synth_memray.py
│ │ │ ├── telco_base.py
│ │ │ ├── telco_data/
│ │ │ │ └── telco-bench.b
│ │ │ └── telco_memray.py
│ │ └── plot.py
│ ├── benchmarks.py
│ └── requirements.txt
├── docs/
│ ├── _static/
│ │ ├── css/
│ │ │ └── custom.css
│ │ ├── flamegraphs/
│ │ │ └── .gitattributes
│ │ └── js/
│ │ └── custom.js
│ ├── _templates/
│ │ └── index.html
│ ├── api.rst
│ ├── attach.rst
│ ├── conf.py
│ ├── examples/
│ │ ├── README.rst
│ │ ├── fibonacci/
│ │ │ └── fib.py
│ │ ├── mandelbrot/
│ │ │ ├── mandelbrot-threaded.py
│ │ │ ├── mandelbrot.py
│ │ │ └── requirements.txt
│ │ ├── nbody/
│ │ │ ├── example.py
│ │ │ └── requirements.txt
│ │ └── sqlite/
│ │ └── example.py
│ ├── flamegraph.rst
│ ├── getting_started.rst
│ ├── index.rst
│ ├── jupyter_magic.rst
│ ├── licenses.rst
│ ├── live.rst
│ ├── manpage.rst
│ ├── memory.rst
│ ├── native_mode.rst
│ ├── overview.rst
│ ├── performance.rst
│ ├── python_allocators.rst
│ ├── run.rst
│ ├── stats.rst
│ ├── summary.rst
│ ├── supported_environments.rst
│ ├── table.rst
│ ├── temporary_allocations.rst
│ ├── transform.rst
│ ├── tree.rst
│ └── tutorials/
│ ├── 1.rst
│ ├── 2.rst
│ ├── 3.rst
│ ├── Dockerfile
│ ├── additional_features.rst
│ ├── exercise_1/
│ │ ├── __init__.py
│ │ └── fibonacci.py
│ ├── exercise_2/
│ │ ├── __init__.py
│ │ └── holding_onto_memory.py
│ ├── exercise_3/
│ │ ├── __init__.py
│ │ └── lru_cache.py
│ ├── index.rst
│ ├── requirements-tutorial.txt
│ ├── solutions/
│ │ ├── exercise_1/
│ │ │ └── fibonacci.py
│ │ ├── exercise_2/
│ │ │ └── holding_onto_memory.py
│ │ └── exercise_3/
│ │ └── lru_cache.py
│ └── tests/
│ ├── __init__.py
│ ├── test_exercise_1.py
│ ├── test_exercise_2.py
│ └── test_exercise_3.py
├── news/
│ └── .gitignore
├── package.json
├── pyproject.toml
├── requirements-docs.txt
├── requirements-extra.txt
├── requirements-test.txt
├── setup.py
├── src/
│ ├── memray/
│ │ ├── __init__.py
│ │ ├── __init__.pyi
│ │ ├── __main__.py
│ │ ├── _destination.py
│ │ ├── _errors.py
│ │ ├── _ipython/
│ │ │ ├── __init__.py
│ │ │ └── flamegraph.py
│ │ ├── _memray/
│ │ │ ├── CMakeLists.txt
│ │ │ ├── __init__.pxd
│ │ │ ├── algorithm.pxd
│ │ │ ├── alloc.h
│ │ │ ├── alloc.pxd
│ │ │ ├── compat.cpp
│ │ │ ├── compat.h
│ │ │ ├── elf_shenanigans.cpp
│ │ │ ├── elf_utils.h
│ │ │ ├── exceptions.h
│ │ │ ├── frame_tree.h
│ │ │ ├── hooks.cpp
│ │ │ ├── hooks.h
│ │ │ ├── hooks.pxd
│ │ │ ├── inject.cpp
│ │ │ ├── linker_shenanigans.h
│ │ │ ├── logging.cpp
│ │ │ ├── logging.h
│ │ │ ├── logging.pxd
│ │ │ ├── lz4_stream.h
│ │ │ ├── macho_shenanigans.cpp
│ │ │ ├── macho_utils.h
│ │ │ ├── native_resolver.cpp
│ │ │ ├── native_resolver.h
│ │ │ ├── native_resolver.pxd
│ │ │ ├── pthread.pxd
│ │ │ ├── python_helpers.cpp
│ │ │ ├── python_helpers.h
│ │ │ ├── record_reader.cpp
│ │ │ ├── record_reader.h
│ │ │ ├── record_reader.pxd
│ │ │ ├── record_writer.cpp
│ │ │ ├── record_writer.h
│ │ │ ├── record_writer.pxd
│ │ │ ├── records.cpp
│ │ │ ├── records.h
│ │ │ ├── records.pxd
│ │ │ ├── sink.cpp
│ │ │ ├── sink.h
│ │ │ ├── sink.pxd
│ │ │ ├── snapshot.cpp
│ │ │ ├── snapshot.h
│ │ │ ├── snapshot.pxd
│ │ │ ├── socket_reader_thread.cpp
│ │ │ ├── socket_reader_thread.h
│ │ │ ├── socket_reader_thread.pxd
│ │ │ ├── source.cpp
│ │ │ ├── source.h
│ │ │ ├── source.pxd
│ │ │ ├── tracking_api.cpp
│ │ │ ├── tracking_api.h
│ │ │ └── tracking_api.pxd
│ │ ├── _memray.pyi
│ │ ├── _memray.pyx
│ │ ├── _memray_test_utils.pyx
│ │ ├── _metadata.py
│ │ ├── _stats.py
│ │ ├── _stats.pyi
│ │ ├── _test.py
│ │ ├── _test_utils.pyi
│ │ ├── _thread_name_interceptor.py
│ │ ├── _version.py
│ │ ├── commands/
│ │ │ ├── __init__.py
│ │ │ ├── _attach.gdb
│ │ │ ├── _attach.lldb
│ │ │ ├── attach.py
│ │ │ ├── common.py
│ │ │ ├── flamegraph.py
│ │ │ ├── live.py
│ │ │ ├── parse.py
│ │ │ ├── run.py
│ │ │ ├── stats.py
│ │ │ ├── summary.py
│ │ │ ├── table.py
│ │ │ ├── transform.py
│ │ │ └── tree.py
│ │ ├── py.typed
│ │ └── reporters/
│ │ ├── __init__.py
│ │ ├── _textual_hacks.py
│ │ ├── assets/
│ │ │ ├── README.md
│ │ │ ├── __init__.py
│ │ │ ├── common.js
│ │ │ ├── common.test.js
│ │ │ ├── flamegraph.js
│ │ │ ├── flamegraph_common.js
│ │ │ ├── table.js
│ │ │ └── temporal_flamegraph.js
│ │ ├── common.py
│ │ ├── flamegraph.py
│ │ ├── frame_tools.py
│ │ ├── stats.py
│ │ ├── summary.py
│ │ ├── table.py
│ │ ├── templates/
│ │ │ ├── __init__.py
│ │ │ ├── assets/
│ │ │ │ ├── .gitattributes
│ │ │ │ ├── flamegraph.css
│ │ │ │ ├── flamegraph.js
│ │ │ │ ├── flamegraph_common.js
│ │ │ │ ├── table.css
│ │ │ │ ├── table.js
│ │ │ │ └── temporal_flamegraph.js
│ │ │ ├── base.html
│ │ │ ├── classic_base.html
│ │ │ ├── flamegraph.html
│ │ │ ├── table.html
│ │ │ └── temporal_flamegraph.html
│ │ ├── transform.py
│ │ ├── tree.css
│ │ ├── tree.py
│ │ ├── tui.css
│ │ └── tui.py
│ └── vendor/
│ ├── libbacktrace/
│ │ ├── .gitignore
│ │ ├── Isaac.Newton-Opticks.txt
│ │ ├── LICENSE
│ │ ├── Makefile.am
│ │ ├── Makefile.in
│ │ ├── README.md
│ │ ├── aclocal.m4
│ │ ├── alloc.c
│ │ ├── allocfail.c
│ │ ├── allocfail.sh
│ │ ├── atomic.c
│ │ ├── backtrace-supported.h.in
│ │ ├── backtrace.c
│ │ ├── backtrace.h
│ │ ├── btest.c
│ │ ├── compile
│ │ ├── config/
│ │ │ ├── enable.m4
│ │ │ ├── lead-dot.m4
│ │ │ ├── libtool.m4
│ │ │ ├── ltoptions.m4
│ │ │ ├── ltsugar.m4
│ │ │ ├── ltversion.m4
│ │ │ ├── lt~obsolete.m4
│ │ │ ├── multi.m4
│ │ │ ├── override.m4
│ │ │ ├── unwind_ipinfo.m4
│ │ │ └── warnings.m4
│ │ ├── config.guess
│ │ ├── config.h.in
│ │ ├── config.sub
│ │ ├── configure
│ │ ├── configure.ac
│ │ ├── debuginfod_support.h
│ │ ├── dwarf.c
│ │ ├── edtest.c
│ │ ├── edtest2.c
│ │ ├── elf.c
│ │ ├── fileline.c
│ │ ├── filenames.h
│ │ ├── filetype.awk
│ │ ├── install-debuginfo-for-buildid.sh.in
│ │ ├── install-sh
│ │ ├── instrumented_alloc.c
│ │ ├── internal.h
│ │ ├── ltmain.sh
│ │ ├── macho.c
│ │ ├── missing
│ │ ├── mmap.c
│ │ ├── mmapio.c
│ │ ├── move-if-change
│ │ ├── mtest.c
│ │ ├── nounwind.c
│ │ ├── pecoff.c
│ │ ├── posix.c
│ │ ├── print.c
│ │ ├── read.c
│ │ ├── simple.c
│ │ ├── sort.c
│ │ ├── state.c
│ │ ├── stest.c
│ │ ├── test-driver
│ │ ├── test_format.c
│ │ ├── testlib.c
│ │ ├── testlib.h
│ │ ├── ttest.c
│ │ ├── unittest.c
│ │ ├── unknown.c
│ │ ├── xcoff.c
│ │ ├── xztest.c
│ │ ├── zstdtest.c
│ │ └── ztest.c
│ ├── libbacktrace-patches/
│ │ ├── 0001-Expose-some-internal-functions-of-libbacktrace.patch
│ │ └── 0002-Add-debuginfod-support-to-libbacktrace.patch
│ └── regenerate_libbacktrace.sh
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ ├── integration/
│ │ ├── __init__.py
│ │ ├── misbehaving_extension/
│ │ │ ├── __init__.py
│ │ │ ├── misbehaving.cpp
│ │ │ └── setup.py
│ │ ├── multithreaded_extension/
│ │ │ ├── __init__.py
│ │ │ ├── main.py
│ │ │ ├── setup.py
│ │ │ └── testext.cpp
│ │ ├── native_extension/
│ │ │ ├── main.py
│ │ │ ├── native_ext.c
│ │ │ └── setup.py
│ │ ├── rpath_extension/
│ │ │ ├── ext.c
│ │ │ ├── setup.py
│ │ │ └── sharedlibs/
│ │ │ └── sharedlib.c
│ │ ├── test_api.py
│ │ ├── test_attach.py
│ │ ├── test_extensions.py
│ │ ├── test_greenlet.py
│ │ ├── test_ipython.py
│ │ ├── test_main.py
│ │ ├── test_native_tracking.py
│ │ ├── test_object_tracking.py
│ │ ├── test_processes.py
│ │ ├── test_record_writer.py
│ │ ├── test_socket.py
│ │ ├── test_threads.py
│ │ ├── test_tracing.py
│ │ └── test_tracking.py
│ ├── test_utils.py
│ ├── unit/
│ │ ├── __init__.py
│ │ ├── conftest.py
│ │ ├── test_allocation_lifetime_aggregator.py
│ │ ├── test_attach.py
│ │ ├── test_cli.py
│ │ ├── test_flamegraph_reporter.py
│ │ ├── test_frame_tools.py
│ │ ├── test_high_water_mark_aggregator.py
│ │ ├── test_highwatermark_command.py
│ │ ├── test_reader.py
│ │ ├── test_stats_reporter.py
│ │ ├── test_summary_reporter.py
│ │ ├── test_table_reporter.py
│ │ ├── test_templates.py
│ │ ├── test_tracker.py
│ │ ├── test_transform_reporter.py
│ │ ├── test_tree_reporter.py
│ │ └── test_tui_reporter.py
│ └── utils.py
├── valgrind.supp
└── webpack.config.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .babelrc
================================================
{
"presets": ["@babel/preset-env"]
}
================================================
FILE: .bumpversion.cfg
================================================
[bumpversion]
current_version = 1.19.2
commit = True
message =
Prepare for {new_version} release
See changelog for more details.
[bumpversion:file:src/memray/_version.py]
================================================
FILE: .clang-format
================================================
BasedOnStyle: LLVM
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: WithoutElse
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: TopLevel
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: true
AfterControlStatement: MultiLine
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterStruct: true
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
BreakStringLiterals: true
ColumnLimit: 105
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 0
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
DerivePointerAlignment: false
FixNamespaceComments: true
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: ".*"
Priority: 1
IndentCaseLabels: true
IndentGotoLabels: false
IndentPPDirectives: AfterHash
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 8
UseTab: Never
================================================
FILE: .devcontainer/devcontainer.json
================================================
{
"name": "Memray development",
"build": {
"context": "..",
"dockerfile": "../Dockerfile"
},
"runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
"onCreateCommand": "pip install -e ."
}
================================================
FILE: .devcontainer/tutorials/devcontainer.json
================================================
{
"name": "Memray tutorials",
"build": {
"context": "../../docs/tutorials",
"dockerfile": "../../docs/tutorials/Dockerfile"
},
"customizations": {
"vscode": {
"settings": {
"python.testing.pytestArgs": ["docs/tutorials/tests"],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.defaultInterpreterPath": "/venv/bin/python"
},
"extensions": ["ms-python.python"]
}
},
"runArgs": ["--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"]
}
================================================
FILE: .github/ISSUE_TEMPLATE/---bug-report.yaml
================================================
name: 🐞 Bug Report
description: If something isn't working as expected
labels: [bug]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: Current Behavior
description: A concise description of what you're experiencing.
validations:
required: false
- type: textarea
attributes:
label: Expected Behavior
description: A concise description of what you expected to happen.
validations:
required: false
- type: textarea
attributes:
label: Steps To Reproduce
description: Steps to reproduce the behavior.
placeholder: |
1. In this environment...
2. With this config...
3. Run '...'
4. See error...
validations:
required: True
- type: input
id: memray_version
attributes:
label: Memray Version
description: What version of Memray are you seeing the problem on?
placeholder: 1.3.0
validations:
required: true
- type: dropdown
id: python_version
attributes:
label: Python Version
description: What version of Python are you running?
multiple: true
options:
- "3.7"
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
- "3.14"
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating System
description: What OS are you seeing the problem on?
multiple: true
options:
- macOS
- Linux
validations:
required: true
- type: textarea
attributes:
label: Anything else?
description: |
Links? References? Anything that will give us more context about the issue you are encountering!
Tip: You can attach images or log files by clicking this area to highlight it and then dragging files in.
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/---feature-request.yaml
================================================
name: 🚀 Feature Request
description: Suggest an idea for this project
labels: [enhancement]
body:
- type: checkboxes
attributes:
label: Is there an existing proposal for this?
description: Please search to see if a proposal already exists for this feature.
options:
- label: I have searched the existing proposals
required: true
- type: textarea
attributes:
label: Is your feature request related to a problem?
description: A clear and concise description of what the problem is
placeholder: |
I have an issue when [...]
validations:
required: True
- type: textarea
attributes:
label: Describe the solution you'd like
description: A clear and concise description of what you want to happen. Add any considered drawbacks.
placeholder: |
I would love if Memray could [...]
validations:
required: True
- type: textarea
attributes:
label: Alternatives you considered
description: A clear and concise description of any alternative solutions or features you've considered.
validations:
required: False
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: true
contact_links:
- name: Long question or idea
url: https://github.com/bloomberg/memray/discussions
about: Ask long-form questions and discuss ideas.
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
================================================
FILE: .github/workflows/build.yml
================================================
name: Tests
on:
push:
branches:
- main
pull_request:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
check_generated_files:
name: "Check if generated files are up to date"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up dependencies
run: |
sudo apt-get update
sudo apt-get install -qy npm git
- name: Check if files are up to date
run: make build-js
- name: Check for changes
run: |
git add -u
changes=$(git status --porcelain)
# Check for changes in regenerated files
if test -n "$changes"; then
echo "Generated files not up to date."
echo "$changes"
echo ""
git diff --staged || true
exit 1
fi
test_in_alpine:
name: "Test in Alpine Linux"
runs-on: ubuntu-latest
container:
image: alpine
options: --cap-add=SYS_PTRACE
steps:
- uses: actions/checkout@v6
- name: Set up dependencies
run: |
apk add --update build-base libunwind-dev lz4-dev musl-dev python3-dev python3-dbg gdb lldb git bash perl perl-datetime build-base perl-app-cpanminus
cpanm Date::Parse
cpanm Capture::Tiny
# Build elfutils
cd /
apk add --update argp-standalone bison bsd-compat-headers bzip2-dev curl curl-dev flex-dev libtool linux-headers musl-fts-dev musl-libintl musl-obstack-dev xz-dev zlib-dev zstd-dev
VERS=0.191
curl -L https://mirrors.kernel.org/sourceware/elfutils/$VERS/elfutils-$VERS.tar.bz2 >./elfutils.tar.bz2
tar -xf elfutils.tar.bz2
cd elfutils-$VERS
CFLAGS='-Wno-error -DFNM_EXTMATCH=0 -g -O3' CXXFLAGS='-Wno-error -DFNM_EXTMATCH=0 -g -O3' ./configure --enable-libdebuginfod --disable-debuginfod --disable-nls --with-zstd
make install
- name: Create virtual environment
run: |
python3 -m venv /venv
- name: Install Python dependencies
run: |
/venv/bin/python -m pip install --upgrade pip
- name: Run tests
env:
PYTHON: /venv/bin/python
run: |
make test-install check-python
lint_and_docs:
name: "Lint and Docs"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Node
uses: actions/setup-node@v6
with:
node-version: 16
- name: Symlink node as nodejs
run: ln -sf "$(which node)" "$(which node)js"
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.10"
- name: Set up dependencies
run: |
sudo apt-get update
sudo apt-get install -qy clang-format npm libdebuginfod-dev libunwind-dev liblz4-dev pkg-config
- name: Install Python dependencies
run: |
python3 -m pip install -r requirements-extra.txt
- name: Install Package
run: |
python3 -m pip install -e .
- name: Lint sources
run: |
make lint
- name: Build docs
run: |
towncrier build --version 99.99 --name memray --keep
make docs
valgrind:
name: "Valgrind & Helgrind"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Python 3.10
uses: actions/setup-python@v6
with:
python-version: "3.10"
- name: Set up dependencies
run: |
sudo apt-get update
sudo apt-get install -qy libdebuginfod-dev libunwind-dev liblz4-dev pkg-config npm valgrind
- name: Install Python dependencies and package
run: |
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements-test.txt
python3 -m pip install -e .
env:
MEMRAY_MINIMIZE_INLINING: 1
- name: Run Valgrind
run: make valgrind
- name: Run Helgrind
run: make helgrind
================================================
FILE: .github/workflows/build_wheels.yml
================================================
name: Wheels
on:
push:
pull_request:
release:
types:
- published
schedule:
# At 12:00 on every day-of-month
- cron: "0 12 */1 * *"
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
build_sdist:
name: Build source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Build sdist
run: pipx run build --sdist
- uses: actions/upload-artifact@v7
with:
name: sdist
path: dist
- uses: actions/upload-artifact@v7
with:
name: tests
path: tests
choose_linux_wheel_types:
name: Decide which wheel types to build
runs-on: ubuntu-latest
steps:
- id: manylinux_x86_64
run: echo "wheel_types=manylinux_x86_64" >> $GITHUB_OUTPUT
- id: musllinux_x86_64
run: echo "wheel_types=musllinux_x86_64" >> $GITHUB_OUTPUT
- id: manylinux_i686
run: echo "wheel_types=manylinux_i686" >> $GITHUB_OUTPUT
- id: manylinux_aarch64
run: echo "wheel_types=manylinux_aarch64" >> $GITHUB_OUTPUT
outputs:
wheel_types: ${{ toJSON(steps.*.outputs.wheel_types) }}
build_linux_wheels:
needs: [build_sdist, choose_linux_wheel_types]
name: ${{ matrix.wheel_type }} wheels
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
wheel_type: ${{ fromJSON(needs.choose_linux_wheel_types.outputs.wheel_types) }}
include:
- os: ubuntu-latest
- wheel_type: manylinux_aarch64
os: ubuntu-24.04-arm
- wheel_type: manylinux_i686
os: ubuntu-latest
cibw_archs_linux: auto32
steps:
- uses: actions/download-artifact@v8
with:
name: sdist
path: dist
- uses: actions/download-artifact@v8
with:
name: tests
path: tests
- name: Extract sdist
run: |
tar zxvf dist/*.tar.gz --strip-components=1
- name: Disable ptrace security restrictions
run: |
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
- name: Build wheels
uses: pypa/cibuildwheel@v3.4.0
env:
CIBW_BUILD: "cp3{7..14}{t,}-${{ matrix.wheel_type }}"
CIBW_ARCHS_LINUX: ${{ matrix.cibw_archs_linux || 'auto' }}
CIBW_PRERELEASE_PYTHONS: True
CIBW_TEST_EXTRAS: test
CIBW_TEST_COMMAND: python -um pytest --log-cli-level=DEBUG -s -vvv {package}/tests
- uses: actions/upload-artifact@v7
with:
name: ${{ matrix.wheel_type }}-wheels
path: ./wheelhouse/*.whl
build_macosx_wheels:
needs: [build_sdist]
name: macosx_${{ matrix.arch }} wheels
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: macos-15-intel
arch: x86_64
- os: macos-14
arch: arm64
steps:
- uses: actions/download-artifact@v8
with:
name: sdist
path: dist
- uses: actions/download-artifact@v8
with:
name: tests
path: tests
- name: Extract sdist
run: |
tar zxvf dist/*.tar.gz --strip-components=1
- name: Sets env vars for compilation
run: |
echo "LZ4_INSTALL_DIR=/tmp/lz4_install" >> $GITHUB_ENV
echo "CFLAGS=-arch ${{matrix.arch}}" >> $GITHUB_ENV
- name: Set x86_64-specific environment variables
if: matrix.arch == 'x86_64'
run: |
echo "MACOSX_DEPLOYMENT_TARGET=10.14" >> $GITHUB_ENV
- name: Set arm64-specific environment variables
if: matrix.arch == 'arm64'
run: |
echo "MACOSX_DEPLOYMENT_TARGET=11.0" >> $GITHUB_ENV
- name: Build wheels
uses: pypa/cibuildwheel@v3.4.0
env:
CIBW_BUILD: "cp3{8..14}{t,}-*"
CIBW_ARCHS: "${{matrix.arch}}"
CIBW_PRERELEASE_PYTHONS: True
CIBW_TEST_EXTRAS: test
CIBW_TEST_COMMAND: python -um pytest --log-cli-level=DEBUG -s -vvv {package}/tests
CIBW_BUILD_VERBOSITY: 1
CFLAGS: "${{env.CFLAGS}} -I${{env.LZ4_INSTALL_DIR}}/include"
LDFLAGS: "-L${{env.LZ4_INSTALL_DIR}}/lib -Wl,-rpath,${{env.LZ4_INSTALL_DIR}}/lib"
PKG_CONFIG_PATH: "${{env.LZ4_INSTALL_DIR}}/lib/pkgconfig"
CIBW_REPAIR_WHEEL_COMMAND_MACOS: "DYLD_LIBRARY_PATH=${{env.LZ4_INSTALL_DIR}}/lib delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"
- uses: actions/upload-artifact@v7
with:
name: macosx_${{ matrix.arch }}-wheels
path: ./wheelhouse/*.whl
build_and_test_wheels:
name: Build and test wheels
needs: [build_linux_wheels, build_macosx_wheels]
runs-on: ubuntu-latest
if: always() # Don't skip this step if a predecessor failed!
steps:
# We can't make a matrix job itself a required check in GitHub,
# so we instead add a job that depends on the two matrix jobs,
# and we mark this job as required instead. This job doesn't do
# any work, it just lets us better manage our required checks.
- if: "!success()"
run: echo "Some builds failed" && exit 1
- run: echo "All builds succeeded!"
upload_pypi:
needs: [build_and_test_wheels, build_sdist]
runs-on: ubuntu-latest
if: github.event_name == 'release' && github.event.action == 'published'
steps:
- uses: actions/download-artifact@v8
with:
# with no name set, it downloads all of the artifacts
path: dist
- run: |
mv dist/sdist/*.tar.gz dist/
mv dist/*-wheels/*.whl dist/
rmdir dist/{sdist,*-wheels}
rm -r dist/tests
ls -R dist
- uses: pypa/gh-action-pypi-publish@release/v1
with:
skip_existing: true
password: ${{ secrets.PYPI_PASSWORD }}
================================================
FILE: .github/workflows/coverage.yml
================================================
name: Coverage
permissions:
pull-requests: write
on:
push:
branches:
- main
pull_request:
branches:
- main
release:
types:
- published
schedule:
# At 12:00 on every day-of-month
- cron: "0 12 */1 * *"
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
coverage:
runs-on: ubuntu-24.04
env:
PYTHON: python3.13
MEMRAY_MINIMIZE_INLINING: 1
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v6
- name: Set up dependencies
run: |
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get update
sudo apt-get install -qy \
pkg-config \
libdebuginfod-dev \
libunwind-dev \
liblz4-dev \
gdb \
lcov \
libdw-dev \
libelf-dev \
${PYTHON}-dev \
${PYTHON}-dbg \
${PYTHON}-venv
- name: Create a virtualenv
run: |
${PYTHON} -m venv /tmp/coverage-venv
- name: Set up PATH
run: |
echo /tmp/coverage-venv/bin >>"$GITHUB_PATH"
echo /home/runner/node_modules/.bin >>"$GITHUB_PATH"
- name: Install Python dependencies
run: |
${PYTHON} -m pip install --upgrade pip cython pkgconfig
make test-install
- name: Disable ptrace security restrictions
run: |
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
- name: Compute C++ coverage
run: |
make ccoverage
- name: Compute Python + Cython coverage
run: |
make pycoverage
- name: Upload C++ report to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: cppcoverage.lcov
flags: cpp
- name: Upload {P,C}ython report to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: pycoverage.lcov
flags: python_and_cython
================================================
FILE: .github/workflows/docs.yml
================================================
name: Docs
on:
push:
branches:
- main
jobs:
publish_docs:
name: Publish docs
runs-on: ubuntu-latest
#if: github.event_name == 'release' && github.event.action == 'published'
permissions:
contents: write
steps:
- uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.10"
- name: Set up dependencies
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -qy libdebuginfod-dev libunwind-dev liblz4-dev pkg-config
- name: Install Python dependencies
run: |
python3 -m pip install -r requirements-extra.txt
- name: Install Package
run: |
python3 -m pip install -e .
- name: Build docs
run: |
make docs
- name: Publish docs to GitHub Pages
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: docs/_build/html
single-commit: true
================================================
FILE: .github/workflows/news-check.yml
================================================
name: News entry check
on:
pull_request:
paths:
- "src/memray/**"
types:
- "opened"
- "reopened"
- "synchronize"
- "labeled"
- "unlabeled"
jobs:
news_entry_check:
runs-on: ubuntu-latest
name: Check for news entry
steps:
- name: "Check for news entry"
uses: brettcannon/check-for-changed-files@v1
with:
file-pattern: |
news/*.rst
NEWS.rst
skip-label: "skip news"
failure-message: "Missing a news file in ${file-pattern}; please add one or apply the ${skip-label} label to the pull request"
================================================
FILE: .github/workflows/sanity-check.yml
================================================
name: Sanity check
on:
pull_request:
types:
- "opened"
- "reopened"
- "synchronize"
- "labeled"
- "unlabeled"
jobs:
commits_check_job:
runs-on: ubuntu-latest
name: Commits Check
steps:
- name: Get PR Commits
id: "get-pr-commits"
uses: tim-actions/get-pr-commits@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: DCO Check
uses: tim-actions/dco@master
with:
commits: ${{ steps.get-pr-commits.outputs.commits }}
================================================
FILE: .github/workflows/test_uv_python.yml
================================================
name: UV Python Tests
on:
push:
branches:
- main
pull_request:
branches:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
test_uv_python:
name: "Test with UV Python 3.14"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install uv and set Python 3.14
uses: astral-sh/setup-uv@v7
with:
python-version: "3.14"
- name: Create virtual environment
run: |
uv venv --python 3.14
- name: Set up system dependencies
run: |
sudo apt-get update
sudo apt-get install -qy \
pkg-config \
libdebuginfod-dev \
libunwind-dev \
liblz4-dev \
gdb \
npm
- name: Install Python dependencies
run: |
uv pip install --upgrade pip cython pkgconfig
uv pip install -r requirements-test.txt
- name: Build package
run: |
make build-js
uv pip install -e .
- name: Disable ptrace security restrictions
run: |
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
- name: Run tests
run: |
uv run pytest -vvv --log-cli-level=info tests
================================================
FILE: .gitignore
================================================
# IDE stuff
.idea/*
# Cmake stuff
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
*.cbp
cmake-build-*/
.cmake
# Cython specific files
src/memray/*.cpp
src/memray/_memray_api.h
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# Asv stuff
.asv
# memray stuff
memray-*
# VSCode
.vscode
# NodeJS
node_modules/
# Vendored files
src/vendor/libbacktrace/install
# pytest-textual-snapshot
snapshot_report.html
================================================
FILE: .pre-commit-config.yaml
================================================
exclude: "^(src/memray/reporters/templates/assets|src/vendor|benchmarks|docs/_static/flamegraphs)/"
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: check-added-large-files
- id: check-json
exclude: "^asv\\.conf\\.json$"
- id: check-merge-conflict
- id: check-toml
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
exclude: "^([.]bumpversion[.]cfg|.*/__snapshots__/)"
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: rst-directive-colons
- id: rst-inline-touching-normal
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: "v0.1.7"
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- repo: https://github.com/psf/black
rev: 23.12.0
hooks:
- id: black
- repo: https://github.com/pycqa/isort
rev: 5.13.2
hooks:
- id: isort
exclude_types: [python]
- repo: https://github.com/sphinx-contrib/sphinx-lint
rev: v0.9.1
hooks:
- id: sphinx-lint
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
hooks:
- id: prettier
args: [--no-editorconfig]
exclude: "^asv\\.conf\\.json$"
exclude_types: [html]
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: v17.0.6
hooks:
- id: clang-format
args: [--Werror, -i]
exclude: "^tests/integration/"
types_or: [c++, c, cuda]
- repo: https://github.com/rstcheck/rstcheck
rev: v6.2.0
hooks:
- id: rstcheck
files: ^news/
types: [rst]
additional_dependencies: ["sphinx"]
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
Before contributing to this repository, first please discuss the change you wish to make via an
issue, or any other method of communication with the maintainers of this repository.
You can also search this project for issues with the following labels:
| Label | Search Term | Description |
| ----------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [good-first-issue](https://github.com/bloomberg/memray/search?q=is%3Aissue+is%3Aopen+label%3Agood-first-issue&type=Issues&utf8=%E2%9C%93) | `is:issue is:open label:good-first-issue` | Recommended for first-time contributors! These are well-defined, and allow a user to get familiar with the project's workflow before tackling more complex issues. |
| [help wanted](https://github.com/bloomberg/memray/search?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22+&type=Issues&utf8=%E2%9C%93) | `is:issue is:open label:"help wanted"` | General issues where contributors help is wanted. |
| [question](https://github.com/bloomberg/memray/search?q=is%3Aissue+is%3Aopen+label%3Aquestion&type=Issues&utf8=%E2%9C%93) | `is:issue is:open label:question` | Open discussions to resolve everything from implementation details to desired functionality. |
## Contribution Licensing
Since this project is distributed under the terms of an [open source license](LICENSE), contributions that
you make are licensed under the same terms. In order for us to be able to accept your contributions,
we will need explicit confirmation from you that you are able and willing to provide them under
these terms, and the mechanism we use to do this is called a Developer's Certificate of Origin
[(DCO)](https://github.com/bloomberg/.github/blob/main/DCO.md). This is very similar to the process
used by the Linux kernel, Samba, and many other major open source projects.
To participate under these terms, all that you must do is include a line like the following as the
last line of the commit message for each commit in your contribution:
Signed-Off-By: Random J. Developer <random@developer.example.org>
The simplest way to accomplish this is to add `-s` or `--signoff` to your `git commit` command.
You must use your real name (sorry, no pseudonyms, and no anonymous contributions).
## Documentation
**Public** modules, functions, classes, and methods must be documented using [Python
docstrings][pep 257]. **Non-public** functions and methods must also be documented for defining the
API contract. In addition to being useful for generating documentation, docstrings add clarity when
looking through the source code or using the [built-in help][builtin-help] system, and can be
leveraged in autocompletion by IDEs.
Please see [PEP 257][] for details on semantics and conventions associated with Python docstrings.
### Docstring style
Docstrings must follow [Google style docstrings][google-style]. This docstring style is more
pleasant to read when browsing the source.
## Type hints
All functions and methods should be type annotated. This allows for static analysis and more
intelligent code completion from tools & IDEs.
## Tests
Changes should always include tests. If this is a bug fix it is a good idea to add the tests as the
first commit of the pull request and the changes to fix the issue in subsequent commits to make it
easier to validate it.
## Pull requests
### Linting your code
Before commiting anything, install the pre-commit hooks:
```shell
python3 -m pip install -r requirements-extra.txt
pre-commit install
```
This will ensure that your contribution passes our linting checks.
### PRs should be linked to a GitHub issue
Before opening a pull request to this repository, first please make sure there is a GitHub issue
where your change has been discussed with the maintainers. Mention the issue number in your pull
request description using one of the
[supported keywords](https://help.github.com/articles/closing-issues-using-keywords/). For example,
adding `Closes: #100` in the pull request description will link the PR with the issue and GitHub
will automatically close the issue upon merging it.
Do not include the issue reference in your commit messages however, add it only in the description
of the PR.
<!-- LINKS -->
[pep 257]: https://www.python.org/dev/peps/pep-0257/ "Docstring Conventions"
[pep 484]: https://www.python.org/dev/peps/pep-0484/ "Type Hints"
[google-style]: https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html "Example Google Style Python Docstrings"
[builtin-help]: https://docs.python.org/3/library/functions.html#help
<!--
vim: tw=99:spell
-->
================================================
FILE: Dockerfile
================================================
FROM debian:bookworm-slim
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --force-yes --no-install-recommends \
build-essential \
libdebuginfod-dev \
libunwind-dev \
liblz4-dev \
pkg-config \
python3-dev \
python3-dbg \
python3-pip \
python3-venv \
make \
cmake \
gdb \
valgrind \
lcov \
nodejs \
npm \
clang-format \
git \
ccache \
wget \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ENV VIRTUAL_ENV=/venv \
PYTHONDONTWRITEBYTECODE=1 \
PATH=/bin:$PATH \
CC=gcc \
CXX=g++
RUN python3 -m venv "$VIRTUAL_ENV"
ENV PATH="${VIRTUAL_ENV}/bin:/usr/lib/ccache:${PATH}" \
PYTHON="${VIRTUAL_ENV}/bin/python" \
MEMRAY_MINIMIZE_INLINING="1"
COPY requirements-test.txt requirements-extra.txt requirements-docs.txt /tmp/
RUN $PYTHON -m pip install -U \
-r /tmp/requirements-extra.txt \
-r /tmp/requirements-test.txt \
-r /tmp/requirements-docs.txt \
cython \
pkgconfig \
setuptools \
wheel
RUN npm install -g prettier
WORKDIR /src
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2022 Bloomberg LP
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: MANIFEST.in
================================================
exclude .clang-format
exclude asv.conf.json
exclude CONTRIBUTING.md
exclude Dockerfile
exclude Jenkinsfile
exclude requirements-*.txt
exclude .medusarc
exclude valgrind.supp
recursive-exclude src/vendor/libbacktrace/install *
recursive-exclude benchmarks *
recursive-exclude debian *
recursive-exclude docker *
recursive-exclude docs *
recursive-exclude src/memray *.cpp *.h
recursive-exclude src/memray *.md
recursive-exclude tests *
recursive-exclude news *
recursive-exclude vendor *
include README.md
include Makefile
include pyproject.toml
include package.json
include package-lock.json
include .bumpversion.cfg
include .babelrc
include webpack.config.js
include NEWS.rst
include .flake8
include src/memray/py.typed
include .pre-commit-config.yaml
recursive-include src/vendor *
recursive-include src/memray *.py
recursive-include src/memray *.pyi
recursive-include src/memray *.html *.js *.css
recursive-include src/memray *.pyx *.pxd
recursive-include src/memray *.gdb *.lldb
recursive-include src/memray/_memray *
recursive-include tools *.sh
================================================
FILE: NEWS.rst
================================================
.. note
You should *NOT* add new change log entries to this file, this
file is managed by towncrier. You *may* edit previous change logs to
fix problems like typo corrections or such.
Changelog
=========
.. towncrier release notes start
memray 1.19.2 (2026-03-12)
--------------------------
Bug Fixes
~~~~~~~~~
- Add support for Python 3.14's tail call interpreter. Memray now correctly identifies Python frame boundaries in native stack traces when Python 3.14 is built with the tail call interpreter enabled (``--with-tail-call-interp``), recognizing LLVM-generated tail call functions alongside traditional ``_PyEval_EvalFrameDefault`` functions. (#836)
- Prevent an ``AssertionError`` when the tracked process exits after the live TUI was closed. (#849)
- Ensure the command line is properly HTML escaped when writing it into flamegraph and table reports. (#885)
- Fix the ``--no-web`` option for ``memray flamegraph``, which was generating broken flame graphs. (#876)
memray 1.19.1 (2025-09-29)
--------------------------
- Fix a bug that caused Memray to refuse to produce stack traces for ``pymalloc`` allocations when ``--trace-python-allocators`` was used. (#832)
memray 1.19.0 (2025-09-26)
--------------------------
Features
~~~~~~~~
- Add a mode that can be used in Python 3.13.3 and newer where Memray will track Python object creation and destruction events, which can be used to find leaked objects (ones that were created during a tracking session and not destroyed before the end of that tracking session). (#752)
- Added ``--no-web`` flag to ``flamegraph`` and ``table`` commands for offline HTML report generation. When this flag is specified, memray bundles all external dependencies (Bootstrap, jQuery, D3, DataTables, Plotly.js) directly into the generated HTML files instead of loading them from CDNs. This enables memray to generate fully functional HTML reports on airgapped systems without internet connectivity. (#790)
- Reduced memory profiling overhead and capture file size by changing how
Python code locations are recorded. This makes allocation tracking
faster, produces smaller capture files, and improves the accuracy of
reports that group allocations by source location. (#801)
Bug Fixes
~~~~~~~~~
- Fix a crash that could occur if tracking was started in one thread while another thread was inside of a trace function installed with ``sys.settrace``. This crash wasn't possible to hit with ``memray run``, but could happen when using ``pytest-memray`` and ``pytest-cov`` together. (#823)
- Fix timestamps on the heap usage line chart when Memray is run on a 32-bit platform. (#826)
memray 1.18.0 (2025-08-07)
--------------------------
Features
~~~~~~~~
- Add a button to the flame graph and table reports for downloading a CSV of the source data of the graph showing RSS and heap memory usage over time. (#769)
- Peak memory usage is now included in the stats reporter. (#771)
- Python 3.14 is now supported. (#804)
- ``memray attach`` now supports attaching to a process using the new built-in ``sys.remote_exec`` when running in Python 3.14, rather than needing to use a debugger to inject itself. Since this is faster and safer, it is the new default, but you can still use the old methods by passing ``--method=gdb`` or ``--method=lldb`` to ``memray attach``. (#805)
- Free-threaded builds of Python 3.14 are now supported. (#808)
Deprecations and Removals
~~~~~~~~~~~~~~~~~~~~~~~~~
- We no longer provide musllinux_1_1 wheels. Previously they were provided for Python 3.7 through 3.13, now we provide musllinux_1_2 wheels for those Python versions instead. The manylinux project dropped support for musllinux_1_1 on November 1st, 2024. (#742)
- We no longer provide manylinux2010 wheels. Previously they were provided for Python 3.7 through 3.12, now we provide manylinux2014 wheels for those Python versions instead. The manylinux project dropped support for manylinux2010 on August 1st, 2022. (#742)
Bug Fixes
~~~~~~~~~
- Update all Memray reporters to consistently use kilobytes rather than kibibytes and ensure that the proper SI unit labels are used. (#774)
- Fix a bug that could have resulted in a use-after-free in a program where Memray's profile hooks were uninstalled by a call to ``PyEval_SetProfileAllThreads``. (#803)
- Fix a potential use-after-free bug in ``memray attach``. (#808)
memray 1.17.2 (2025-05-08)
--------------------------
Bug Fixes
~~~~~~~~~
- Fix a bug causing ``memray flamegraph --temporal`` to fail to detect the
correct high water mark for the selected time span. (#759)
memray 1.17.1 (2025-04-04)
--------------------------
Bug Fixes
~~~~~~~~~
- Fix a bug that could result in an infinite loop on ARM Linux systems when a process that Memray is attached to abruptly dies. (#737)
memray 1.17.0 (2025-04-03)
--------------------------
Bug Fixes
~~~~~~~~~
- Fix a bug with macOS version 15.4 that was causing memray to crash when the internal TLS variables were being created or destroyed. (#732)
- A backwards incompatible change in Textual prevented the ``memray tree`` and ``memray attach`` commands from working properly. Work around this to support the latest Textual versions. (#734)
memray 1.16.0 (2025-03-06)
--------------------------
Bug Fixes
~~~~~~~~~
- Fix the tree reporter's rendering of emojis to work for Textual 2, which no longer supports directly assigning label text using emoji shortcodes. (#714)
memray 1.15.0 (2024-12-03)
--------------------------
Bug Fixes
~~~~~~~~~
- Fix some crashes caused by interposing symbols in memray itself (#685)
- Fixed a bug that was causing tracking of runtime libraries that are part of the linker cache not work in macOS 15. (#693)
- Fix a crash when a greenlet switch happens after Memray's profile function has been deactivated or replaced. (#700)
memray 1.14.0 (2024-09-09)
--------------------------
Features
~~~~~~~~
- Wheels are now published for Python 3.13, though we don't yet support free-threaded (no GIL) builds. (#658)
Bug Fixes
~~~~~~~~~
- Fix a lock ordering deadlock in libc between a Memray lock and a lock internal to dlopen. (#549)
- Ensure flame graphs stay in flame mode when the user has selected it.
Previously clicking the "Hide Irrelevant Frames" or "Hide Import System Frames"
checkboxes would switch the flame graph back to icicle mode. (#656)
- Fix a race condition that was able to cause strange exception messages if two different threads tried to initialize Memray tracking at once. (#667)
memray 1.13.4 (2024-07-18)
--------------------------
Bug Fixes
~~~~~~~~~
- A backwards-incompatible change released in Textual 0.73 caused the ``memray tree`` reporter to start with no nodes expanded. This release adds a workaround to restore the old behavior of expanding the first child of each node. (#648)
memray 1.13.3 (2024-07-02)
--------------------------
Bug Fixes
~~~~~~~~~
- Fix a bug that could result in truncated reports for applications that fork without calling :c:func:`PyOS_BeforeFork`, including by using `multiprocessing` with the "spawn" start method (the default on macOS). (#644)
memray 1.13.2 (2024-06-27)
--------------------------
Bug Fixes
~~~~~~~~~
- Fix a bug that could in rare circumstances result in a stack overflow while processing native mode stacks. (#639)
Miscellaneous
~~~~~~~~~~~~~
- Upgrade our vendored copy of ``libbacktrace``, used for reporting native stacks, to the latest version. (#639)
memray 1.13.1 (2024-06-23)
--------------------------
Bug Fixes
~~~~~~~~~
- Fix a deadlock that could occur on some Linux systems when resolving debug information using debuginfod. (#634)
memray 1.13.0 (2024-06-18)
--------------------------
Features
~~~~~~~~
- Add :doc:`a tutorial <tutorials/index>` to the Memray documentation. (#590)
- Include the thread name in the live TUI. (#562)
- Capture the name attribute of Python `threading.Thread` objects. (#562)
- Allow using Ctrl+Z to suspend ``memray tree`` and the live mode TUI. (#581)
- Add a button in the live-mode TUI to show allocations from all threads at once. (#589)
- Vendor ``libdebuginfod`` into our Linux wheels, so that debuginfod integration can be used without any dependency on system-installed libraries. (#592)
Bug Fixes
~~~~~~~~~
- Fix dynamic toggling between descriptions like "Pause" vs "Unpause" or "Show" vs "Hide" in the footer of the live-mode TUI and tree reporter. This was broken by changes introduced in Textual 0.61 (and again by Textual 0.63). (#597)
- Correctly localize the start and end time in the "Stats" modal when an HTML report was generated on a different machine than the one it is being displayed on. (#611)
- Fix a crash in old macOS versions (<11.0) due to the inavailability of some linker cache APIs. (#615)
- Fix reporting of "Own Memory" in the ``live`` and ``summary`` reporters. A bug in our summation caused us to undercount functions' direct allocations. (#617)
Miscellaneous
~~~~~~~~~~~~~
- Builds from source now work for Python 3.13. Wheels are not yet published for 3.13 because it is not yet ABI stable. (#622)
- Link our Linux wheels against the latest version of ``elfutils``. (#592)
memray 1.12.0 (2024-03-07)
--------------------------
Features
~~~~~~~~
- Allow ``--temporal`` and ``--max-memory-records`` to be used with our :ref:`Jupyter magic <Jupyter integration>`. (#538)
- Automatically use aggregated capture files for the :ref:`Jupyter magic <Jupyter integration>` whenever possible, reducing the amount of disk space needed for temporary files. (#538)
- Expose the main thread id in the FileReader's metadata attribute. (#560)
Bug Fixes
~~~~~~~~~
- Fix a bug that was causing ``dlopen`` to not load shared libraries that have an RPATH/RUNPATH set. (#525)
- Fix a bug where the tree reporter would fail to populate the code pane with relevant lines if the line where the allocation occurred was too near the start of the file. (#544)
- Fix a bug causing the first entry of ``sys.path`` to be erroneously overwritten by ``memray run`` when the Python interpreter was launched with the ``-I`` or ``-P`` flag, or when the ``PYTHONSAFEPATH`` environment variable was set. (#552)
memray 1.11.0 (2023-12-04)
--------------------------
Features
~~~~~~~~
- Migrate the :doc:`live TUI <live>` to Textual. This provides a greatly improved user experience, including the ability to scroll to view rows that don't fit on the screen. (#274)
- Add a new documentation page to serve as :ref:`an overview of memory concepts <memory overview>`, to help users better interpret the memory profiles provided by Memray. (#496)
- Where possible, leverage ``pkg-config`` when building the extension from source, picking up appropriate compiler and linker flags automatically. (#498)
- Port the tree reporter to be an interactive Textual App. (#499)
Bug Fixes
~~~~~~~~~
- Fixed a bug that caused ``memray attach`` to fail with newer LLDB versions, including on macOS Sonoma. (#490)
- Limit the number of memory records displayed in reporters by default. This will help displaying flamegraphs for long capture sessions. (#491)
- When generating a ``--leaks`` flamegraph, don't show a warning that the ``pymalloc`` allocator is in use if ``--trace-python-allocators`` was used when generating the capture file. (#492)
- Ensure that we update our terminal progress bars to 100% when processing finishes. (#494)
memray 1.10.0 (2023-10-05)
--------------------------
Features
~~~~~~~~
- Add support for :ref:`inverted flame graphs`. In an inverted flame graph, the
roots are the functions that allocated memory, and the children of any given
node represent the percentage of that node's allocations that can be attributed
to a particular caller. The inverted flame graph is very helpful in analyzing
where memory is being spent in aggregate. You can generate one by passing the
``--inverted`` flag to ``memray flamegraph``. (#439)
- ``memray attach`` now supports ``--aggregate`` to produce :ref:`aggregated capture files <aggregated capture files>`. (#455)
- ``memray attach`` has been enhanced to allow tracking for only a set period of
time. (#458)
- A new ``memray detach`` command allows you to manually deactivate tracking that
was started by a previous call to ``memray attach``. (#458)
- Python 3.12 is now supported. (#474)
Bug Fixes
~~~~~~~~~
- Update ``memray attach`` on Linux to prefer GDB over LLDB for injecting itself into the process being attached to. We've had several reports of problems with the Linux LLDB, and hope this change will help give Linux users a better experience by default. You can still explicitly use LLDB on Linux even when GDB is detected by running ``memray attach --method=lldb``. (#449)
- Fix a memory leak in Memray itself when many different capture files are opened by a single Memray process and native stacks are being reported. This issue primarily affected ``pytest-memray``. (#473)
- Fix a crash in MacOS Sonoma when using system Framework libraries, like when using the ``pyobjc`` library. (#477)
memray 1.9.1 (2023-08-01)
-------------------------
Bug Fixes
~~~~~~~~~
- Fix an issue that stopped Memray's experimental support for ``greenlet`` from working with versions of the ``greenlet`` module older than 1.0. (#432)
- Fix a bug leading to a deadlock when Memray is used to profile an application that uses the jemalloc implementation of ``malloc``. (#433)
- Fix a bug causing the ``summary`` reporter to generate empty reports. (#435)
memray 1.9.0 (2023-07-28)
-------------------------
Features
~~~~~~~~
- Allow to report the current version of Memray via a ``--version/-V`` command line parameter (#420)
- Add pause/unpause keybindings to the live reporter that allows the user to pause the live reporter to analyse the current results without pausing the running program (#418)
Bug Fixes
~~~~~~~~~
- Support building with Cython 3 (#425)
memray 1.8.1 (2023-06-20)
-------------------------
Features
~~~~~~~~
- When the high water mark being shown by a temporal flame graph is before the first memory snapshot or after the last one, tell the user so by highlighting a region beyond the end of the memory usage plot. (#399)
Bug Fixes
~~~~~~~~~
- Prevent a totally empty memory plot from being shown on flame graphs when the tracked process completes before any periodic memory snapshots are captured. (#399)
- Fix a bug that prevented the temporal high water mark flame graph from showing the flame graph of a high water mark that occurred after the final periodic memory snapshot was captured. (#399)
- Fix a bug that prevented Memray from intercepting functions in shared objects that are part of the dyld shared cache in macOS Ventura. (#401)
memray 1.8.0 (2023-06-09)
-------------------------
Features
~~~~~~~~
- Allow ``memray stats`` to output a JSON report via ``--json`` flag. (#377)
- We now publish x86-64 musllinux_1_1 wheels, compatible with Alpine Linux. (#379)
- We now support :ref:`temporal flame graphs`, which provide an exciting new way of analyzing your process's memory usage over time. (#391)
Bug Fixes
~~~~~~~~~
- Fix a bug where a non-import call on the same line as an ``import`` statement would be hidden by the "Hide Import System Frames" checkbox of a flame graph. (#329)
- Fixed a bug that was hitting an assert when constructing hybrid stack frames in Python 3.11 when no eval symbols are available. (#334)
- Change the font color used by the ``%%memray_flamegraph`` Jupyter magic's progress updates for better contrast on the JupyterLab dark theme. (#344)
- Fix a bug that could result in a deadlock when tracking a process linked against an old version of musl libc. (#379)
memray 1.7.0 (2023-02-21)
-------------------------
Features
~~~~~~~~
- ``memray run`` now supports ``--aggregate`` to produce :ref:`aggregated capture files <aggregated capture files>`, which can be much smaller but aren't able to be used for generating every type of report. (#277)
- Add integration with debuginfod to automatically download debug information for binaries if it is available. (#308)
- Flame graphs produced by ``memray flamegraph`` are now around 85% smaller. (#314)
Bug Fixes
~~~~~~~~~
- ``memray run --live`` and ``memray run --live-remote`` silently dropped the ``--trace-python-allocators`` flag. This has been fixed, and the flag is now properly propagated from the CLI to the tracker. (#283)
- Fix a bug that was causing Memray to crash when the Tracker is being destroyed and some other thread is still registering allocations or deallocations (#289)
- Work around `a bug in GDB versions before 10.1 <https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=da1df1db9ae43050c8de62e4842428ddda7eb509>`_ that could cause ``memray attach`` to fail. (#310)
- Work around `a bug in LLDB on Linux <https://github.com/llvm/llvm-project/issues/60408>`_ that could cause ``memray attach`` to hang. (#311)
memray 1.6.0 (2023-01-17)
-------------------------
Features
~~~~~~~~
- Speed up native allocation tracking by up to 45% (#294)
Bug Fixes
~~~~~~~~~
- ``memray run --live`` and ``memray run --live-remote`` silently dropped the ``--trace-python-allocators`` flag. This has been fixed, and the flag is now properly propagated from the CLI to the tracker. (#283)
- Fix a bug that was causing Memray to crash when the Tracker is being destroyed and some other thread is still registering allocations or deallocations (#289)
Memray 1.5.0 (2022-12-09)
-------------------------
Features
~~~~~~~~
- Memray is now fully supported on macOS, and the warnings that macOS support is experimental have been dropped. (#194)
- Add a checkbox to flamegraphs that allows hiding frames from the import system (#261)
- ``memray attach`` can be used to :doc:`attach to a running process <attach>` (#266)
- Consider frames from the import system as "irrelevant" in the generated flamegraphs. (#268)
memray 1.4.1 (2022-11-11)
-------------------------
Bug Fixes
~~~~~~~~~
- Fix a crash that can happen when two different threads try to register frames at the same time without the GIL held. (#251)
memray 1.4.0 (2022-10-31)
-------------------------
Features
~~~~~~~~
- Add a new ``transform`` subcomand that allows transforming Memray capture files into output files compatible with other tools. We're starting by supporting conversions to the *gprof2dot* format, which allows producing graph-like reports when combined with *graphviz*. (#200)
- Added a new ``--temporary-allocations`` option to the ``flamegraph``, ``table``, ``tree``, and ``summary`` reporters for showing the :doc:`temporary allocations </temporary_allocations>` instead of the high water mark ones. (#201)
- When the ``greenlet`` module is in use, also assign a distinct thread ID to each greenlet. Greenlets aren't threads, but they are distinct threads of execution within a single process, with distinct stacks, so assigning different thread IDs to each makes it easier to interpret reports where ``greenlet`` was used. (#209)
- Use a monotonic counter to generate thread IDs, rather than using the pthread ID. Those pthread IDs can be reused, making it difficult to tell what thread performed an allocation. (#209)
- Print a warning when we detect that the Python interpreter was built without debug information or without symbols, letting the user know in advance that these conditions may result in incorrect stack traces or missing filenames and line numbers. (#211)
- A new ``%%memray_flamegraph`` Jupyter cell magic is provided by ``%load_ext memray``, and can be used to memory profile code directly in a Jupyter notebook. (#237)
- Add ``csv`` as a possible target format for ``memray transform``, producing a report of all of the allocations that made up the process's high water mark of allocated memory. This CSV file can then be loaded and analyzed using libraries like ``pandas``. (#241)
Deprecations and Removals
~~~~~~~~~~~~~~~~~~~~~~~~~
- Up until now, if the program being profiled included a Cython module built with profiling support enabled, those Cython functions would show up in our Python call stacks. This was rarely useful in practice, as most Cython libraries aren't distributed with profiling support enabled, and supporting this had a surprisingly high maintenance cost. We've removed this integration, so you'll need to use ``--native`` mode to see inside of Cython modules. We are not considering this a backwards-incompatible change, since it does not affect any of our public interfaces (though it could affect the contents of reports generated by Memray). (#206)
Bug Fixes
~~~~~~~~~
- Fix a bug that caused incorrect ``--native`` mode stacks on Python 3.11 for allocations performed directly by the interpreter's eval loop. (#209)
- Fix a crash when an extension module terminates the program using non-Python APIs under tracking. (#228)
memray 1.3.1 (2022-08-30)
-------------------------
Bug Fixes
~~~~~~~~~
- Prevent a crash that could occur when forked processes that have been under tracking without ``follow_fork=True`` remove the profiling function with pending frames needed to be flushed to the results file. (#196)
memray 1.3.0 (2022-08-18)
-------------------------
Features
~~~~~~~~
- We now capture Python stacks for allocations made by threads that existed before the Memray tracker was started. (#130)
- Add support for Python 3.11 (#138)
- Add support for MacOS. (#174)
- Add experimental support for Greenlet. (#185)
Bug Fixes
~~~~~~~~~
- Prevent a crash that could occur if the Memray API was used to stop and later restart tracking while another thread was running Python code. (#152)
- Prevent a use-after-free bug that could result in a crash if ``sys.setprofile()`` was called while Memray was tracking. Now if ``sys.setprofile()`` is called, all future allocations on that thread will report unknown Python stacks, instead of potentially incorrect stacks. (#176)
Memray 1.2.0 (2022-07-11)
-------------------------
Features
~~~~~~~~
- Add a progress bar indicator to the record processing phases in the different reporters so users can have an approximate idea of how much time processing the result files will take. (#111)
- The ``memray stats`` reporter is now up to 50% faster, and its output is easier to interpret because it now processes all allocations by default. (#136)
- Add a line showing the heap size over time to the memory plot in the html-based reporters (which already showed the resident size over time). (#142)
Deprecations and Removals
~~~~~~~~~~~~~~~~~~~~~~~~~
- Remove the ``--include-all-allocations`` / ``-a`` argument to the ``memray stats`` reporter. Previously this was too slow to be used by default, but now that it has been sped up, it doesn't make sense to use anything else. The old default behavior of only processing allocations that made up the high water mark of the application's memory usage was confusing and misleading. (#136)
Bug Fixes
~~~~~~~~~
- Fix a crash with SIGBUS when the file system fills up while ``memray run`` is writing a capture file. (#117)
- Recognize when a capture file has been truncated (most likely because the tracked process was killed unexpectedly) and ignore any incomplete record at the end of the file. (#129)
- Fix the histogram used by the ``memray stats`` reporter to choose sane bin sizes when all captured allocations are the same size. (#133)
- Fix the aggregation by location at the bottom of the ``memray stats`` report when the ``--include-all-allocations`` option is used. (#134)
- Fix a bug causing deallocations with ``free`` and ``munmap`` to be included in the reported "Total allocations" count of ``memray stats --include-all-allocations``. (#136)
- Fix the two "largest allocating locations" sections in the ``memray stats`` report to actually aggregate by location. Previously they were aggregating by distinct stacks, so if two different paths hit the same line of code, it would be counted separately instead of together. (#136)
- Fix a bug causing memory freed by ``munmap`` to be incorrectly added into the reported "Total memory allocated" of ``memray stats --include-all-allocations``. (#136)
- Exclude ``PYMALLOC_FREE`` from the allocator type distribution (other deallocators were already being ignored, but this recently added one was missed). (#136)
- Fix the ``memray stats`` histogram to be based on the actual sizes of all allocations. Previously it only saw the sizes after a rollup by stack had already been performed, so it was binning allocation sizes that had already been summed. (#136)
- Fixed a bug where aggregating native call stacks could give misleading results on aarch64 under some circumstances. (#141)
- Fix a bug that made ``memray run --live -c`` fail if the command to run contained double quotes. (#147)
- Ensure our TUI isn't displaying stale data by periodically flushing the latest available data from the tracker (rather than only flushing when a buffer fills up). (#147)
- Fix the handling of the thread switch commands in the live mode TUI before the first allocation has been seen. (#147)
memray 1.1.0 (2022-05-16)
-------------------------
Features
~~~~~~~~
- Finalize and document the Memray :doc:`tracking API <api>`. (#42)
- Ensure that wheels built by ``make dist`` are reproducible (so that running the build twice produces identical artifacts). (#47)
- Reduce the size of the ``memray run`` capture file by around 20% by using a more efficient encoding for which allocator was used to perform a given allocation and whether we :ref:`captured a native stack <native tracking>` for that allocation. (#52)
- Support ``memray run -c "..."`` to profile an in-line script provided on the command line. (#61)
- The capture files produced by ``memray run`` are now around 90% smaller thanks to a more efficient encoding scheme for the binary files. (#67)
- Add support for Alpine Linux and musl libc. (#75)
- Capture allocations made through the C99 ``aligned_alloc`` function. (#79)
- By default the capture file will now be compressed using LZ4 after tracking completes. This temporarily requires extra disk space while the compression runs, but results in roughly 75% less disk space required in the end. Compression can be disabled with ``--no-compress``. (#82)
- Speed up tracking by around 5% by building with link-time optimization (LTO). (#91)
- Add a new ``--trace-python-allocators`` option to ``memray run`` that allows tracking all allocations made using the Python allocators. This will result in bigger output files and slower profiling but it allows getting insights about all of the interpreter's memory allocations. (#92)
Bug Fixes
~~~~~~~~~
- Previously we attempted to read all allocation records into memory when processing a capture file in our reporters. This could fail on large files, so now we process the file in a streaming fashion instead. (#62)
- Make ``memray run`` perform the same modifications to `sys.path` as the interpreter itself would when running a script. (#86)
- Fixed a bug in the :doc:`stats reporter <stats>` that could result in the largest allocations being omitted from the histogram. (#95)
- Fixed a bug that caused Memray reporters to display incorrect stacks when :ref:`native tracking` was enabled and native allocations from different locations occurred underneath the same Python stack. (#96)
Miscellaneous
~~~~~~~~~~~~~
- Support the latest versions of Rich (previously we pinned to an old version due to some formatting changes in more recent versions). (#98)
memray 1.0.3 (2022-04-21)
-------------------------
Features
~~~~~~~~
- Add ``memray`` as a command line entry point. (#20)
memray 1.0.2 (2022-04-12)
-------------------------
Features
~~~~~~~~
- Add publishing of ManyLinux2010 wheels for 64 and 32 bit systems. (#2)
Bug Fixes
~~~~~~~~~
- Fix 32 bit builds. (#2)
memray 1.0.0 (2022-04-09)
-------------------------
- Initial release.
================================================
FILE: README.md
================================================
<p align="center">
<img src="https://raw.githubusercontent.com/bloomberg/memray/main/docs/_static/images/logo.png" width="70%">
</p>
---
[](https://pypi.org/project/memray)
[](https://pypi.org/project/memray)
[](https://pypi.org/project/memray)
[](https://pypi.org/project/memray)
[](https://pypi.org/project/memray)
[](https://pypistats.org/packages/memray)
[](https://anaconda.org/conda-forge/memray)
[](https://github.com/bloomberg/memray/actions/workflows/build.yml)
[](https://github.com/bloomberg/memray/actions/workflows/build_wheels.yml)
[](https://github.com/bloomberg/memray/actions/workflows/coverage.yml)
[](https://github.com/psf/black)
<p align="center"><img src="https://raw.githubusercontent.com/bloomberg/memray/main/docs/_static/images/output.png" alt="Memray output"></p>
Memray is a memory profiler for Python. It can track memory allocations in Python code, in native extension
modules, and in the Python interpreter itself. It can generate several different types of reports to help you
analyze the captured memory usage data. While commonly used as a CLI tool, it can also be used as a library to
perform more fine-grained profiling tasks.
Notable features:
- 🕵️♀️ Traces every function call so it can accurately represent the call stack, unlike sampling profilers.
- ℭ Also handles native calls in C/C++ libraries so the entire call stack is present in the results.
- 🏎 Blazing fast! Profiling slows the application only slightly. Tracking native code is somewhat slower,
but this can be enabled or disabled on demand.
- 📈 It can generate various reports about the collected memory usage data, like flame graphs.
- 🧵 Works with Python threads.
- 👽🧵 Works with native-threads (e.g. C++ threads in C extensions).
Memray can help with the following problems:
- Analyze allocations in applications to help discover the cause of high memory usage.
- Find memory leaks.
- Find hotspots in code that cause a lot of allocations.
> **Note**
> Memray only works on Linux and MacOS, and cannot be installed on other platforms.
<p align="center">
<img src="https://raw.githubusercontent.com/bloomberg/memray/main/docs/_static/images/quotes.png" width="100%">
</p>
# Help us improve Memray!
We are constantly looking for feedback from our awesome community ❤️. If you
have used Memray to solve a problem, profile an application, find a memory leak
or anything else, please let us know! We would love to hear about your
experience and how Memray helped you.
Please, consider writing your story in the [Success
Stories discussion page](https://github.com/bloomberg/memray/discussions/226).
It really makes a difference!
# Installation
Memray requires Python 3.7+ and can be easily installed using most common Python
packaging tools. We recommend installing the latest stable release from
[PyPI](https://pypi.org/project/memray/) with pip:
```shell
python3 -m pip install memray
```
Notice that Memray contains a C extension so releases are distributed as binary
wheels as well as the source code. If a binary wheel is not available for your system
(Linux x86/x64 or macOS), you'll need to ensure that all the dependencies are satisfied on the
system where you are doing the installation.
## Building from source
If you wish to build Memray from source you need the following binary dependencies in your system:
- libdebuginfod-dev (for Linux)
- libunwind (for Linux)
- liblz4
Check your package manager on how to install these dependencies (for example `apt-get install build-essential python3-dev libdebuginfod-dev libunwind-dev liblz4-dev` in Debian-based systems
or `brew install lz4` in MacOS). Note that you may need to teach the compiler where to find the header and library files of the dependencies. For
example, in MacOS with `brew` you may need to run:
```shell
export CFLAGS="-I$(brew --prefix lz4)/include" LDFLAGS="-L$(brew --prefix lz4)/lib -Wl,-rpath,$(brew --prefix lz4)/lib"
```
before installing `memray`. Check the documentation of your package manager to know the location of the header and library
files for more detailed information.
If you are building on MacOS, you will also need to set the deployment target.
```shell
export MACOSX_DEPLOYMENT_TARGET=10.14
```
Once you have the binary dependencies installed, you can clone the repository and follow with the normal building process:
```shell
git clone git@github.com:bloomberg/memray.git memray
cd memray
python3 -m venv ../memray-env/ # just an example, put this wherever you want
source ../memray-env/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -e . -r requirements-test.txt -r requirements-extra.txt
```
This will install Memray in the virtual environment in development mode (the `-e` of the last `pip install` command).
If you plan to contribute back, you should install the pre-commit hooks:
```shell
pre-commit install
```
This will ensure that your contribution passes our linting checks.
# Documentation
You can find the latest documentation available [here](https://bloomberg.github.io/memray/).
# Usage
There are many ways to use Memray. The easiest way is to use it as a command line tool to run your script, application, or library.
```
usage: memray [-h] [-v] {run,flamegraph,table,live,tree,parse,summary,stats} ...
Memory profiler for Python applications
Run `memray run` to generate a memory profile report, then use a reporter command
such as `memray flamegraph` or `memray table` to convert the results into HTML.
Example:
$ python3 -m memray run -o output.bin my_script.py
$ python3 -m memray flamegraph output.bin
positional arguments:
{run,flamegraph,table,live,tree,parse,summary,stats}
Mode of operation
run Run the specified application and track memory usage
flamegraph Generate an HTML flame graph for peak memory usage
table Generate an HTML table with all records in the peak memory usage
live Remotely monitor allocations in a text-based interface
tree Generate a tree view in the terminal for peak memory usage
parse Debug a results file by parsing and printing each record in it
summary Generate a terminal-based summary report of the functions that allocate most memory
stats Generate high level stats of the memory usage in the terminal
optional arguments:
-h, --help Show this help message and exit
-v, --verbose Increase verbosity. Option is additive and can be specified up to 3 times
-V, --version Displays the current version of Memray
Please submit feedback, ideas, and bug reports by filing a new issue at https://github.com/bloomberg/memray/issues
```
To use Memray over a script or a single python file you can use:
```shell
python3 -m memray run my_script.py
```
If you normally run your application with `python3 -m my_module`, you can use the `-m` flag with `memray run`:
```shell
python3 -m memray run -m my_module
```
You can also invoke Memray as a command line tool without having to use `-m` to invoke it as a module:
```shell
memray run my_script.py
memray run -m my_module
```
The output will be a binary file (like `memray-my_script.2369.bin`) that you can analyze in different ways. One way is to use the `memray flamegraph` command to generate a flame graph:
```shell
memray flamegraph my_script.2369.bin
```
This will produce an HTML file with a flame graph of the memory usage that you can inspect with your favorite browser. There are multiple other reporters that you can use to generate other types of reports, some of them generating terminal-based output and some of them generating HTML files. Here is an example of a Memray flamegraph:
<img src="https://github.com/bloomberg/memray/blob/main/docs/_static/images/flamegraph_example.png?raw=true" align="center"/>
## Pytest plugin
If you want an easy and convenient way to use `memray` in your test suite, you can consider using [pytest-memray](https://github.com/bloomberg/pytest-memray). Once installed, this pytest plugin allows you to simply add `--memray` to the command line invocation:
```shell
pytest --memray tests/
```
And will automatically get a report like this:
```
python3 -m pytest tests --memray
=============================================================================================================================== test session starts ================================================================================================================================
platform linux -- Python 3.8.10, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /mypackage, configfile: pytest.ini
plugins: cov-2.12.0, memray-0.1.0
collected 21 items
tests/test_package.py ..................... [100%]
================================================================================================================================= MEMRAY REPORT ==================================================================================================================================
Allocations results for tests/test_package.py::some_test_that_allocates
📦 Total memory allocated: 24.4MiB
📏 Total allocations: 33929
📈 Peak memory usage: 10.431MB
📊 Histogram of allocation sizes: |▂ █ |
🥇 Biggest allocating functions:
- parse:/opt/bb/lib/python3.8/ast.py:47 -> 3.0MiB
- parse:/opt/bb/lib/python3.8/ast.py:47 -> 2.3MiB
- _visit:/opt/bb/lib/python3.8/site-packages/astroid/transforms.py:62 -> 576.0KiB
- parse:/opt/bb/lib/python3.8/ast.py:47 -> 517.6KiB
- __init__:/opt/bb/lib/python3.8/site-packages/astroid/node_classes.py:1353 -> 512.0KiB
```
You can also use some of the included markers to make tests
fail if the execution of said test allocates more memory than allowed:
```python
@pytest.mark.limit_memory("24 MB")
def test_foobar():
# do some stuff that allocates memory
```
To learn more on how the plugin can be used and configured check out [the plugin documentation](https://pytest-memray.readthedocs.io).
# Native mode
Memray supports tracking native C/C++ functions as well as Python functions. This can be especially useful when profiling applications that have C extensions (such as `numpy` or `pandas`) as this gives a holistic vision of how much memory is allocated by the extension and how much is allocated by Python itself.
To activate native tracking, you need to provide the `--native` argument when using the `run` subcommand:
```shell
memray run --native my_script.py
```
This will automatically add native information to the result file and it will be automatically used by any reporter (such the flamegraph or table reporters). This means that instead of seeing this in the flamegraphs:
<img src="https://github.com/bloomberg/memray/blob/main/docs/_static/images/mandelbrot_operation_non_native.png?raw=true" align="center"/>
You will now be able to see what's happening inside the Python calls:
<img src="https://github.com/bloomberg/memray/blob/main/docs/_static/images/mandelbrot_operation_native.png?raw=true" align="center"/>
Reporters display native frames in a different color than Python frames. They can also be distinguished by looking at the file location in a frame (Python frames will generally be generated from files with a .py extension while native frames will be generated from files with extensions like .c, .cpp or .h).
# Live mode
<p align="center"><img src="https://raw.githubusercontent.com/bloomberg/memray/main/docs/_static/images/live_animated.webp" alt="Memray output"></p>
Memray's live mode runs a script or a module in a terminal-based interface that allows you to interactively inspect its memory usage while it runs. This is useful for debugging scripts or modules that take a long time to run or that exhibit multiple complex memory patterns. You can use the `--live` option to run the script or module in live mode:
```shell
memray run --live my_script.py
```
or if you want to execute a module:
```shell
memray run --live -m my_module
```
This will show the following TUI interface in your terminal:
<img src="https://raw.githubusercontent.com/bloomberg/memray/main/docs/_static/images/live_running.png" align="center"/>
## Sorting results
The results are displayed in descending order of total memory allocated by a function and the subfunctions called by it. You can change the ordering with the following keyboard shortcuts:
- t (default): Sort by total memory
- o: Sort by own memory
- a: Sort by allocation count
In most terminals you can also click the "Sort by Total", "Sort by Own", and "Sort by Allocations" buttons on the footer.
The sorted column's heading is underlined.
## Viewing different threads
By default, the live command will present the main thread of the program. You can look at different threads of the program by pressing the greater than and less than keys, `<` and `>`. In most terminals you can also click the "Previous Thread" and "Next Thread" buttons on the footer.
<img src="https://github.com/bloomberg/memray/blob/main/docs/_static/images/live_different_thread.png?raw=true" align="center"/>
# API
In addition to tracking Python processes from a CLI using `memray run`, it is also possible to programmatically enable tracking within a running Python program.
```py
import memray
with memray.Tracker("output_file.bin"):
print("Allocations will be tracked until the with block ends")
```
For details, see the [API documentation](https://bloomberg.github.io/memray/api.html).
# License
Memray is Apache-2.0 licensed, as found in the [LICENSE](LICENSE) file.
# Code of Conduct
- [Code of Conduct](https://github.com/bloomberg/.github/blob/main/CODE_OF_CONDUCT.md)
This project has adopted a Code of Conduct. If you have any concerns about the Code, or behavior that you have experienced in the project, please contact us at opensource@bloomberg.net.
# Security Policy
- [Security Policy](https://github.com/bloomberg/memray/security/policy)
If you believe you have identified a security vulnerability in this project, please send an email to the project team at opensource@bloomberg.net, detailing the suspected issue and any methods you've found to reproduce it.
Please do NOT open an issue in the GitHub repository, as we'd prefer to keep vulnerability reports private until we've had an opportunity to review and address them.
# Contributing
We welcome your contributions to help us improve and extend this project!
Below you will find some basic steps required to be able to contribute to the project. If you have any questions about this process or any other aspect of contributing to a Bloomberg open source project, feel free to send an email to opensource@bloomberg.net and we'll get your questions answered as quickly as we can.
## Contribution Licensing
Since this project is distributed under the terms of an [open source license](LICENSE), contributions that
you make are licensed under the same terms. In order for us to be able to accept your contributions,
we will need explicit confirmation from you that you are able and willing to provide them under
these terms, and the mechanism we use to do this is called a Developer's Certificate of Origin
[(DCO)](https://github.com/bloomberg/.github/blob/main/DCO.md). This is very similar to the process
used by the Linux kernel, Samba, and many other major open source projects.
To participate under these terms, all that you must do is include a line like the following as the
last line of the commit message for each commit in your contribution:
Signed-Off-By: Random J. Developer <random@developer.example.org>
The simplest way to accomplish this is to add `-s` or `--signoff` to your `git commit` command.
You must use your real name (sorry, no pseudonyms, and no anonymous contributions).
## Steps
- Create an Issue, select 'Feature Request', and explain the proposed change.
- Follow the guidelines in the issue template presented to you.
- Submit the Issue.
- Submit a Pull Request and link it to the Issue by including "#<issue number>" in the Pull Request summary.
================================================
FILE: asv.conf.json
================================================
{
// The version of the config file format. Do not change, unless
// you know what you are doing.
"version": 1,
// The name of the project being benchmarked
"project": "memray",
// The project's homepage
"project_url": "",
// The URL or local path of the source code repository for the
// project being benchmarked
"repo": ".",
// The Python project's subdirectory in your repo. If missing or
// the empty string, the project is assumed to be located at the root
// of the repository.
// "repo_subdir": "",
// Customizable commands for building, installing, and
// uninstalling the project. See asv.conf.json documentation.
//
// "install_command": ["in-dir={env_dir} python -mpip install {wheel_file}"],
// "uninstall_command": ["return-code=any python -mpip uninstall -y {project}"],
"build_command": [
"python -m pip install cython pkgconfig",
"python setup.py build",
"PIP_NO_BUILD_ISOLATION=false python -mpip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}"
],
// List of branches to benchmark. If not provided, defaults to "main"
// (for git) or "default" (for mercurial).
"branches": ["main"], // for git
// "branches": ["default"], // for mercurial
// The DVCS being used. If not set, it will be automatically
// determined from "repo" by looking at the protocol in the URL
// (if remote), or by looking for special directories, such as
// ".git" (if local).
// "dvcs": "git",
// The tool to use to create environments. May be "conda",
// "virtualenv" or other value depending on the plugins in use.
// If missing or the empty string, the tool will be automatically
// determined by looking for tools on the PATH environment
// variable.
"environment_type": "virtualenv",
// timeout in seconds for installing any dependencies in environment
// defaults to 10 min
//"install_timeout": 600,
// the base URL to show a commit for the project.
// "show_commit_url": "http://github.com/owner/project/commit/",
// The Pythons you'd like to test against. If not provided, defaults
// to the current version of Python used to run `asv`.
// "pythons": ["2.7", "3.6"],
// The list of conda channel names to be searched for benchmark
// dependency packages in the specified order
// "conda_channels": ["conda-forge", "defaults"],
// The matrix of dependencies to test. Each key is the name of a
// package (in PyPI) and the values are version numbers. An empty
// list or empty string indicates to just test against the default
// (latest) version. null indicates that the package is to not be
// installed. If the package to be tested is only available from
// PyPi, and the 'environment_type' is conda, then you can preface
// the package name by 'pip+', and the package will be installed via
// pip (with all the conda available packages installed first,
// followed by the pip installed packages).
//
// "matrix": {
// "numpy": ["1.6", "1.7"],
// "six": ["", null], // test with and without six installed
// "pip+emcee": [""], // emcee is only available for install with pip.
// },
// Combinations of libraries/python versions can be excluded/included
// from the set to test. Each entry is a dictionary containing additional
// key-value pairs to include/exclude.
//
// An exclude entry excludes entries where all values match. The
// values are regexps that should match the whole string.
//
// An include entry adds an environment. Only the packages listed
// are installed. The 'python' key is required. The exclude rules
// do not apply to includes.
//
// In addition to package names, the following keys are available:
//
// - python
// Python version, as in the *pythons* variable above.
// - environment_type
// Environment type, as above.
// - sys_platform
// Platform, as in sys.platform. Possible values for the common
// cases: 'linux2', 'win32', 'cygwin', 'darwin'.
//
// "exclude": [
// {"python": "3.2", "sys_platform": "win32"}, // skip py3.2 on windows
// {"environment_type": "conda", "six": null}, // don't run without six on conda
// ],
//
// "include": [
// // additional env for python2.7
// {"python": "2.7", "numpy": "1.8"},
// // additional env if run on windows+conda
// {"platform": "win32", "environment_type": "conda", "python": "2.7", "libpython": ""},
// ],
// The directory (relative to the current directory) that benchmarks are
// stored in. If not provided, defaults to "benchmarks"
"benchmark_dir": "benchmarks",
// The directory (relative to the current directory) to cache the Python
// environments in. If not provided, defaults to "env"
"env_dir": ".asv/env",
// The directory (relative to the current directory) that raw benchmark
// results are stored in. If not provided, defaults to "results".
"results_dir": ".asv/results",
// The directory (relative to the current directory) that the html tree
// should be written to. If not provided, defaults to "html".
"html_dir": ".asv/html",
// The number of characters to retain in the commit hashes.
// "hash_length": 8,
// `asv` will cache results of the recent builds in each
// environment, making them faster to install next time. This is
// the number of builds to keep, per environment.
// "build_cache_size": 2,
// The commits after which the regression search in `asv publish`
// should start looking for regressions. Dictionary whose keys are
// regexps matching to benchmark names, and values corresponding to
// the commit (exclusive) after which to start looking for
// regressions. The default is to start from the first commit
// with results. If the commit is `null`, regression detection is
// skipped for the matching benchmark.
//
// "regressions_first_commits": {
// "some_benchmark": "352cdf", // Consider regressions only after this commit
// "another_benchmark": null, // Skip regression detection altogether
// },
// The thresholds for relative change in results, after which `asv
// publish` starts reporting regressions. Dictionary of the same
// form as in ``regressions_first_commits``, with values
// indicating the thresholds. If multiple entries match, the
// maximum is taken. If no entry matches, the default is 5%.
//
// "regressions_thresholds": {
// "some_benchmark": 0.01, // Threshold of 1%
// "another_benchmark": 0.5, // Threshold of 50%
// },
}
================================================
FILE: benchmarks/__init__.py
================================================
================================================
FILE: benchmarks/benchmarking/__main__.py
================================================
import dataclasses
import json
import pathlib
import subprocess
import sys
import tempfile
from typing import List
from .plot import plot_diff
CASES_DIR = pathlib.Path(__file__).parent / "cases"
RESULTS_DIR = pathlib.Path(__file__).parent / "results"
DOCUTILS_DATA = pathlib.Path(__file__).parent / "cases" / "docutils_data" / "docs"
TELCO_DATA = pathlib.Path(__file__).parent / "cases" / "telco_data" / "telco-bench.b"
@dataclasses.dataclass
class Case:
name: str
file_name: str
arguments: List[str] = dataclasses.field(default_factory=list)
def run_case(
self,
run_name: str,
template_file: pathlib.Path,
tracker_options: str,
results_file: str,
) -> None:
with tempfile.TemporaryDirectory() as tmpdirname:
case_file = pathlib.Path(tmpdirname) / f"{self.file_name}.py"
code = template_file.read_text()
case_file.write_text(code)
helper_file = pathlib.Path(tmpdirname) / "memray_helper.py"
helper_code = (
"import memray\nimport contextlib\n"
f"def get_tracker():\n return {tracker_options}"
)
helper_file.write_text(helper_code)
results_file = RESULTS_DIR / results_file
print(f"Running {self.name} with arguments {self.arguments} - {run_name}")
subprocess.run(
[sys.executable, case_file, "-o", results_file] + self.arguments,
check=True,
)
def run(self) -> None:
template_file = CASES_DIR / f"{self.file_name}_memray.py"
if not template_file.exists():
raise ValueError(f"Case {self.name} does not exist.")
self.run_case(
"", template_file, "contextlib.nullcontext()", f"{self.name}.json"
)
self.run_case(
"memray base",
template_file,
"memray.Tracker('/dev/null')",
f"{self.name}_memray.json",
)
self.run_case(
"memray python allocators",
template_file,
"memray.Tracker('/dev/null', trace_python_allocators=True)",
f"{self.name}_memray_python_allocators.json",
)
self.run_case(
"memray python native",
template_file,
"memray.Tracker('/dev/null', native_traces=True)",
f"{self.name}_memray_python_native.json",
)
self.run_case(
"memray python all",
template_file,
"memray.Tracker('/dev/null', trace_python_allocators=True, native_traces=True)",
f"{self.name}_memray_python_all.json",
)
CASES = [
Case("docutils", "docutils_html", [f"--doc_root={DOCUTILS_DATA}"]),
Case("raytrace", "raytrace", []),
Case("fannkuch", "fannkuch", []),
Case("pprint", "pprint_format", []),
Case("mdp", "mdp", []),
Case("async_tree", "async_tree", ["none"]),
Case("async_tree_io", "async_tree", ["io"]),
Case("async_tree_mem", "async_tree", ["memoization"]),
Case("async_tree_cpu_io", "async_tree", ["cpu_io_mixed"]),
Case("deltablue", "deltablue", []),
Case("nbody", "nbody", []),
Case("nqueens", "nqueens", []),
Case("regex_dna", "regex_dna", []),
Case("go", "go", []),
Case("hexion", "hexion", []),
Case("meteor_context", "meteor_context", []),
Case("json_dumps", "json_dumps", []),
Case("json_loads", "json_loads", []),
Case(
"picke_pure_python",
"pickles",
[
"pickle",
"--pure-python",
],
),
Case("picke", "pickles", ["pickle"]),
Case(
"unpicke_pure_python",
"pickles",
[
"unpickle",
"--pure-python",
],
),
Case("unpicke", "pickles", ["unpickle"]),
Case(
"pickle_list_pure_python",
"pickles",
[
"pickle_list",
"--pure-python",
],
),
Case("pickle_list", "pickles", ["pickle_list"]),
Case(
"unpickle_list_pure_python",
"pickles",
[
"unpickle_list",
"--pure-python",
],
),
Case("unpickle_list", "pickles", ["unpickle_list"]),
Case(
"pickle_dict_pure_python",
"pickles",
[
"pickle_dict",
"--pure-python",
],
),
Case("pickle_dict", "pickles", ["pickle_dict"]),
Case("spectral_norm", "spectral_norm", []),
Case("telco", "telco", [f"--doc_root={TELCO_DATA}"]),
Case("sqlite_synth", "sqlite_synth", []),
Case("regex_v8", "regex_v8", []),
Case("regex_effbot", "regex_effbot", []),
Case("regex_effbot_bytes", "regex_effbot", ["--force_bytes"]),
]
@dataclasses.dataclass
class BenchmarkResult:
name: str
data: List
def gather_benchmarks(cases):
results = []
names = ("", "Defaut", "Python allocators", "Native", "Python allocators + Native")
extensions = (
"",
"_memray",
"_memray_python_allocators",
"_memray_python_native",
"_memray_python_all",
)
for name, extension in zip(names, extensions):
type_results = []
for case in cases:
memray_results_file = RESULTS_DIR / f"{case.name}{extension}.json"
data = json.loads(memray_results_file.read_text())
type_results.append(data)
results.append(BenchmarkResult(name=name, data=type_results))
return results
if __name__ == "__main__":
# if RESULTS_DIR.exists():
# raise RuntimeError(f"Results directory {RESULTS_DIR} already exists")
# RESULTS_DIR.mkdir()
for case in CASES:
case.run()
base_results, *memray_results = gather_benchmarks(CASES)
for memray_result in memray_results:
plot_diff(
memray_result,
base_results,
f"plot_{memray_result.name}.png".replace(" ", "_").lower(),
f"Overhead of Memray with {memray_result.name}",
)
================================================
FILE: benchmarks/benchmarking/cases/__init__.py
================================================
================================================
FILE: benchmarks/benchmarking/cases/async_tree_base.py
================================================
"""
Benchmark for async tree workload, which calls asyncio.gather() on a tree
(6 levels deep, 6 branches per level) with the leaf nodes simulating some
(potentially) async work (depending on the benchmark variant). Benchmark
variants include:
1) "none": No actual async work in the async tree.
2) "io": All leaf nodes simulate async IO workload (async sleep 50ms).
3) "memoization": All leaf nodes simulate async IO workload with 90% of
the data memoized
4) "cpu_io_mixed": Half of the leaf nodes simulate CPU-bound workload and
the other half simulate the same workload as the
"memoization" variant.
"""
import sys
import asyncio
import math
import random
NUM_RECURSE_LEVELS = 6
NUM_RECURSE_BRANCHES = 6
RANDOM_SEED = 0
IO_SLEEP_TIME = 0.05
MEMOIZABLE_PERCENTAGE = 90
CPU_PROBABILITY = 0.5
FACTORIAL_N = 500
class AsyncTree:
def __init__(self):
self.cache = {}
# set to deterministic random, so that the results are reproducible
random.seed(RANDOM_SEED)
async def mock_io_call(self):
await asyncio.sleep(IO_SLEEP_TIME)
async def workload_func(self):
raise NotImplementedError("To be implemented by each variant's derived class.")
async def recurse(self, recurse_level):
if recurse_level == 0:
await self.workload_func()
return
await asyncio.gather(
*[self.recurse(recurse_level - 1) for _ in range(NUM_RECURSE_BRANCHES)]
)
async def run(self):
await self.recurse(NUM_RECURSE_LEVELS)
class NoneAsyncTree(AsyncTree):
async def workload_func(self):
return
class IOAsyncTree(AsyncTree):
async def workload_func(self):
await self.mock_io_call()
class MemoizationAsyncTree(AsyncTree):
async def workload_func(self):
# deterministic random, seed set in AsyncTree.__init__()
data = random.randint(1, 100)
if data <= MEMOIZABLE_PERCENTAGE:
if self.cache.get(data):
return data
self.cache[data] = True
await self.mock_io_call()
return data
class CpuIoMixedAsyncTree(MemoizationAsyncTree):
async def workload_func(self):
# deterministic random, seed set in AsyncTree.__init__()
if random.random() < CPU_PROBABILITY:
# mock cpu-bound call
return math.factorial(FACTORIAL_N)
else:
return await MemoizationAsyncTree.workload_func(self)
def add_metadata(runner):
runner.metadata["description"] = "Async tree workloads."
runner.metadata["async_tree_recurse_levels"] = NUM_RECURSE_LEVELS
runner.metadata["async_tree_recurse_branches"] = NUM_RECURSE_BRANCHES
runner.metadata["async_tree_random_seed"] = RANDOM_SEED
runner.metadata["async_tree_io_sleep_time"] = IO_SLEEP_TIME
runner.metadata["async_tree_memoizable_percentage"] = MEMOIZABLE_PERCENTAGE
runner.metadata["async_tree_cpu_probability"] = CPU_PROBABILITY
runner.metadata["async_tree_factorial_n"] = FACTORIAL_N
def add_cmdline_args(cmd, args):
cmd.append(args.benchmark)
def add_parser_args(parser):
parser.add_argument(
"benchmark",
choices=BENCHMARKS,
help="""\
Determines which benchmark to run. Options:
1) "none": No actual async work in the async tree.
2) "io": All leaf nodes simulate async IO workload (async sleep 50ms).
3) "memoization": All leaf nodes simulate async IO workload with 90% of
the data memoized
4) "cpu_io_mixed": Half of the leaf nodes simulate CPU-bound workload and
the other half simulate the same workload as the
"memoization" variant.
""",
)
BENCHMARKS = {
"none": NoneAsyncTree,
"io": IOAsyncTree,
"memoization": MemoizationAsyncTree,
"cpu_io_mixed": CpuIoMixedAsyncTree,
}
def run_benchmark(benchmark):
async_tree_class = BENCHMARKS[benchmark]
async_tree = async_tree_class()
asyncio.run(async_tree.run())
if __name__ == "__main__":
benchmark = sys.argv[1]
run_benchmark(benchmark)
================================================
FILE: benchmarks/benchmarking/cases/async_tree_memray.py
================================================
"""
Benchmark for async tree workload, which calls asyncio.gather() on a tree
(6 levels deep, 6 branches per level) with the leaf nodes simulating some
(potentially) async work (depending on the benchmark variant). Benchmark
variants include:
1) "none": No actual async work in the async tree.
2) "io": All leaf nodes simulate async IO workload (async sleep 50ms).
3) "memoization": All leaf nodes simulate async IO workload with 90% of
the data memoized
4) "cpu_io_mixed": Half of the leaf nodes simulate CPU-bound workload and
the other half simulate the same workload as the
"memoization" variant.
"""
import asyncio
import math
import random
from memray_helper import get_tracker
import pyperf
NUM_RECURSE_LEVELS = 6
NUM_RECURSE_BRANCHES = 6
RANDOM_SEED = 0
IO_SLEEP_TIME = 0.05
MEMOIZABLE_PERCENTAGE = 90
CPU_PROBABILITY = 0.5
FACTORIAL_N = 500
class AsyncTree:
def __init__(self):
self.cache = {}
# set to deterministic random, so that the results are reproducible
random.seed(RANDOM_SEED)
async def mock_io_call(self):
await asyncio.sleep(IO_SLEEP_TIME)
async def workload_func(self):
raise NotImplementedError("To be implemented by each variant's derived class.")
async def recurse(self, recurse_level):
if recurse_level == 0:
await self.workload_func()
return
await asyncio.gather(
*[self.recurse(recurse_level - 1) for _ in range(NUM_RECURSE_BRANCHES)]
)
async def run(self):
with get_tracker():
await self.recurse(NUM_RECURSE_LEVELS)
class NoneAsyncTree(AsyncTree):
async def workload_func(self):
return
class IOAsyncTree(AsyncTree):
async def workload_func(self):
await self.mock_io_call()
class MemoizationAsyncTree(AsyncTree):
async def workload_func(self):
# deterministic random, seed set in AsyncTree.__init__()
data = random.randint(1, 100)
if data <= MEMOIZABLE_PERCENTAGE:
if self.cache.get(data):
return data
self.cache[data] = True
await self.mock_io_call()
return data
class CpuIoMixedAsyncTree(MemoizationAsyncTree):
async def workload_func(self):
# deterministic random, seed set in AsyncTree.__init__()
if random.random() < CPU_PROBABILITY:
# mock cpu-bound call
return math.factorial(FACTORIAL_N)
else:
return await MemoizationAsyncTree.workload_func(self)
def add_metadata(runner):
runner.metadata["description"] = "Async tree workloads."
runner.metadata["async_tree_recurse_levels"] = NUM_RECURSE_LEVELS
runner.metadata["async_tree_recurse_branches"] = NUM_RECURSE_BRANCHES
runner.metadata["async_tree_random_seed"] = RANDOM_SEED
runner.metadata["async_tree_io_sleep_time"] = IO_SLEEP_TIME
runner.metadata["async_tree_memoizable_percentage"] = MEMOIZABLE_PERCENTAGE
runner.metadata["async_tree_cpu_probability"] = CPU_PROBABILITY
runner.metadata["async_tree_factorial_n"] = FACTORIAL_N
def add_cmdline_args(cmd, args):
cmd.append(args.benchmark)
def add_parser_args(parser):
parser.add_argument(
"benchmark",
choices=BENCHMARKS,
help="""\
Determines which benchmark to run. Options:
1) "none": No actual async work in the async tree.
2) "io": All leaf nodes simulate async IO workload (async sleep 50ms).
3) "memoization": All leaf nodes simulate async IO workload with 90% of
the data memoized
4) "cpu_io_mixed": Half of the leaf nodes simulate CPU-bound workload and
the other half simulate the same workload as the
"memoization" variant.
""",
)
BENCHMARKS = {
"none": NoneAsyncTree,
"io": IOAsyncTree,
"memoization": MemoizationAsyncTree,
"cpu_io_mixed": CpuIoMixedAsyncTree,
}
if __name__ == "__main__":
runner = pyperf.Runner(add_cmdline_args=add_cmdline_args)
add_metadata(runner)
add_parser_args(runner.argparser)
args = runner.parse_args()
benchmark = args.benchmark
async_tree_class = BENCHMARKS[benchmark]
async_tree = async_tree_class()
runner.bench_async_func(f"async_tree_{benchmark}", async_tree.run)
================================================
FILE: benchmarks/benchmarking/cases/deltablue_base.py
================================================
"""
deltablue.py
============
Ported for the PyPy project.
Contributed by Daniel Lindsley
This implementation of the DeltaBlue benchmark was directly ported
from the `V8's source code`_, which was in turn derived
from the Smalltalk implementation by John Maloney and Mario
Wolczko. The original Javascript implementation was licensed under the GPL.
It's been updated in places to be more idiomatic to Python (for loops over
collections, a couple magic methods, ``OrderedCollection`` being a list & things
altering those collections changed to the builtin methods) but largely retains
the layout & logic from the original. (Ugh.)
.. _`V8's source code`: (https://github.com/v8/v8/blob/master/benchmarks/deltablue.js)
"""
# The JS variant implements "OrderedCollection", which basically completely
# overlaps with ``list``. So we'll cheat. :D
class OrderedCollection(list):
pass
class Strength(object):
REQUIRED = None
STRONG_PREFERRED = None
PREFERRED = None
STRONG_DEFAULT = None
NORMAL = None
WEAK_DEFAULT = None
WEAKEST = None
def __init__(self, strength, name):
super(Strength, self).__init__()
self.strength = strength
self.name = name
@classmethod
def stronger(cls, s1, s2):
return s1.strength < s2.strength
@classmethod
def weaker(cls, s1, s2):
return s1.strength > s2.strength
@classmethod
def weakest_of(cls, s1, s2):
if cls.weaker(s1, s2):
return s1
return s2
@classmethod
def strongest(cls, s1, s2):
if cls.stronger(s1, s2):
return s1
return s2
def next_weaker(self):
strengths = {
0: self.__class__.WEAKEST,
1: self.__class__.WEAK_DEFAULT,
2: self.__class__.NORMAL,
3: self.__class__.STRONG_DEFAULT,
4: self.__class__.PREFERRED,
# TODO: This looks like a bug in the original code. Shouldn't this be
# ``STRONG_PREFERRED? Keeping for porting sake...
5: self.__class__.REQUIRED,
}
return strengths[self.strength]
# This is a terrible pattern IMO, but true to the original JS implementation.
Strength.REQUIRED = Strength(0, "required")
Strength.STRONG_PREFERRED = Strength(1, "strongPreferred")
Strength.PREFERRED = Strength(2, "preferred")
Strength.STRONG_DEFAULT = Strength(3, "strongDefault")
Strength.NORMAL = Strength(4, "normal")
Strength.WEAK_DEFAULT = Strength(5, "weakDefault")
Strength.WEAKEST = Strength(6, "weakest")
class Constraint(object):
def __init__(self, strength):
super(Constraint, self).__init__()
self.strength = strength
def add_constraint(self):
global planner
self.add_to_graph()
planner.incremental_add(self)
def satisfy(self, mark):
global planner
self.choose_method(mark)
if not self.is_satisfied():
if self.strength == Strength.REQUIRED:
print("Could not satisfy a required constraint!")
return None
self.mark_inputs(mark)
out = self.output()
overridden = out.determined_by
if overridden is not None:
overridden.mark_unsatisfied()
out.determined_by = self
if not planner.add_propagate(self, mark):
print("Cycle encountered")
out.mark = mark
return overridden
def destroy_constraint(self):
global planner
if self.is_satisfied():
planner.incremental_remove(self)
else:
self.remove_from_graph()
def is_input(self):
return False
class UrnaryConstraint(Constraint):
def __init__(self, v, strength):
super(UrnaryConstraint, self).__init__(strength)
self.my_output = v
self.satisfied = False
self.add_constraint()
def add_to_graph(self):
self.my_output.add_constraint(self)
self.satisfied = False
def choose_method(self, mark):
if self.my_output.mark != mark and Strength.stronger(
self.strength, self.my_output.walk_strength
):
self.satisfied = True
else:
self.satisfied = False
def is_satisfied(self):
return self.satisfied
def mark_inputs(self, mark):
# No-ops.
pass
def output(self):
# Ugh. Keeping it for consistency with the original. So much for
# "we're all adults here"...
return self.my_output
def recalculate(self):
self.my_output.walk_strength = self.strength
self.my_output.stay = not self.is_input()
if self.my_output.stay:
self.execute()
def mark_unsatisfied(self):
self.satisfied = False
def inputs_known(self, mark):
return True
def remove_from_graph(self):
if self.my_output is not None:
self.my_output.remove_constraint(self)
self.satisfied = False
class StayConstraint(UrnaryConstraint):
def __init__(self, v, string):
super(StayConstraint, self).__init__(v, string)
def execute(self):
# The methods, THEY DO NOTHING.
pass
class EditConstraint(UrnaryConstraint):
def __init__(self, v, string):
super(EditConstraint, self).__init__(v, string)
def is_input(self):
return True
def execute(self):
# This constraint also does nothing.
pass
class Direction(object):
# Hooray for things that ought to be structs!
NONE = 0
FORWARD = 1
BACKWARD = -1
class BinaryConstraint(Constraint):
def __init__(self, v1, v2, strength):
super(BinaryConstraint, self).__init__(strength)
self.v1 = v1
self.v2 = v2
self.direction = Direction.NONE
self.add_constraint()
def choose_method(self, mark):
if self.v1.mark == mark:
if self.v2.mark != mark and Strength.stronger(
self.strength, self.v2.walk_strength
):
self.direction = Direction.FORWARD
else:
self.direction = Direction.BACKWARD
if self.v2.mark == mark:
if self.v1.mark != mark and Strength.stronger(
self.strength, self.v1.walk_strength
):
self.direction = Direction.BACKWARD
else:
self.direction = Direction.NONE
if Strength.weaker(self.v1.walk_strength, self.v2.walk_strength):
if Strength.stronger(self.strength, self.v1.walk_strength):
self.direction = Direction.BACKWARD
else:
self.direction = Direction.NONE
else:
if Strength.stronger(self.strength, self.v2.walk_strength):
self.direction = Direction.FORWARD
else:
self.direction = Direction.BACKWARD
def add_to_graph(self):
self.v1.add_constraint(self)
self.v2.add_constraint(self)
self.direction = Direction.NONE
def is_satisfied(self):
return self.direction != Direction.NONE
def mark_inputs(self, mark):
self.input().mark = mark
def input(self):
if self.direction == Direction.FORWARD:
return self.v1
return self.v2
def output(self):
if self.direction == Direction.FORWARD:
return self.v2
return self.v1
def recalculate(self):
ihn = self.input()
out = self.output()
out.walk_strength = Strength.weakest_of(self.strength, ihn.walk_strength)
out.stay = ihn.stay
if out.stay:
self.execute()
def mark_unsatisfied(self):
self.direction = Direction.NONE
def inputs_known(self, mark):
i = self.input()
return i.mark == mark or i.stay or i.determined_by is None
def remove_from_graph(self):
if self.v1 is not None:
self.v1.remove_constraint(self)
if self.v2 is not None:
self.v2.remove_constraint(self)
self.direction = Direction.NONE
class ScaleConstraint(BinaryConstraint):
def __init__(self, src, scale, offset, dest, strength):
self.direction = Direction.NONE
self.scale = scale
self.offset = offset
super(ScaleConstraint, self).__init__(src, dest, strength)
def add_to_graph(self):
super(ScaleConstraint, self).add_to_graph()
self.scale.add_constraint(self)
self.offset.add_constraint(self)
def remove_from_graph(self):
super(ScaleConstraint, self).remove_from_graph()
if self.scale is not None:
self.scale.remove_constraint(self)
if self.offset is not None:
self.offset.remove_constraint(self)
def mark_inputs(self, mark):
super(ScaleConstraint, self).mark_inputs(mark)
self.scale.mark = mark
self.offset.mark = mark
def execute(self):
if self.direction == Direction.FORWARD:
self.v2.value = self.v1.value * self.scale.value + self.offset.value
else:
self.v1.value = (self.v2.value - self.offset.value) / self.scale.value
def recalculate(self):
ihn = self.input()
out = self.output()
out.walk_strength = Strength.weakest_of(self.strength, ihn.walk_strength)
out.stay = ihn.stay and self.scale.stay and self.offset.stay
if out.stay:
self.execute()
class EqualityConstraint(BinaryConstraint):
def execute(self):
self.output().value = self.input().value
class Variable(object):
def __init__(self, name, initial_value=0):
super(Variable, self).__init__()
self.name = name
self.value = initial_value
self.constraints = OrderedCollection()
self.determined_by = None
self.mark = 0
self.walk_strength = Strength.WEAKEST
self.stay = True
def __repr__(self):
# To make debugging this beast from pdb easier...
return "<Variable: %s - %s>" % (self.name, self.value)
def add_constraint(self, constraint):
self.constraints.append(constraint)
def remove_constraint(self, constraint):
self.constraints.remove(constraint)
if self.determined_by == constraint:
self.determined_by = None
class Planner(object):
def __init__(self):
super(Planner, self).__init__()
self.current_mark = 0
def incremental_add(self, constraint):
mark = self.new_mark()
overridden = constraint.satisfy(mark)
while overridden is not None:
overridden = overridden.satisfy(mark)
def incremental_remove(self, constraint):
out = constraint.output()
constraint.mark_unsatisfied()
constraint.remove_from_graph()
unsatisfied = self.remove_propagate_from(out)
strength = Strength.REQUIRED
# Do-while, the Python way.
repeat = True
while repeat:
for u in unsatisfied:
if u.strength == strength:
self.incremental_add(u)
strength = strength.next_weaker()
repeat = strength != Strength.WEAKEST
def new_mark(self):
self.current_mark += 1
return self.current_mark
def make_plan(self, sources):
mark = self.new_mark()
plan = Plan()
todo = sources
while len(todo):
c = todo.pop(0)
if c.output().mark != mark and c.inputs_known(mark):
plan.add_constraint(c)
c.output().mark = mark
self.add_constraints_consuming_to(c.output(), todo)
return plan
def extract_plan_from_constraints(self, constraints):
sources = OrderedCollection()
for c in constraints:
if c.is_input() and c.is_satisfied():
sources.append(c)
return self.make_plan(sources)
def add_propagate(self, c, mark):
todo = OrderedCollection()
todo.append(c)
while len(todo):
d = todo.pop(0)
if d.output().mark == mark:
self.incremental_remove(c)
return False
d.recalculate()
self.add_constraints_consuming_to(d.output(), todo)
return True
def remove_propagate_from(self, out):
out.determined_by = None
out.walk_strength = Strength.WEAKEST
out.stay = True
unsatisfied = OrderedCollection()
todo = OrderedCollection()
todo.append(out)
while len(todo):
v = todo.pop(0)
for c in v.constraints:
if not c.is_satisfied():
unsatisfied.append(c)
determining = v.determined_by
for c in v.constraints:
if c != determining and c.is_satisfied():
c.recalculate()
todo.append(c.output())
return unsatisfied
def add_constraints_consuming_to(self, v, coll):
determining = v.determined_by
cc = v.constraints
for c in cc:
if c != determining and c.is_satisfied():
# I guess we're just updating a reference (``coll``)? Seems
# inconsistent with the rest of the implementation, where they
# return the lists...
coll.append(c)
class Plan(object):
def __init__(self):
super(Plan, self).__init__()
self.v = OrderedCollection()
def add_constraint(self, c):
self.v.append(c)
def __len__(self):
return len(self.v)
def __getitem__(self, index):
return self.v[index]
def execute(self):
for c in self.v:
c.execute()
# Main
def chain_test(n):
"""
This is the standard DeltaBlue benchmark. A long chain of equality
constraints is constructed with a stay constraint on one end. An
edit constraint is then added to the opposite end and the time is
measured for adding and removing this constraint, and extracting
and executing a constraint satisfaction plan. There are two cases.
In case 1, the added constraint is stronger than the stay
constraint and values must propagate down the entire length of the
chain. In case 2, the added constraint is weaker than the stay
constraint so it cannot be accomodated. The cost in this case is,
of course, very low. Typical situations lie somewhere between these
two extremes.
"""
global planner
planner = Planner()
prev, first, last = None, None, None
# We need to go up to n inclusively.
for i in range(n + 1):
name = "v%s" % i
v = Variable(name)
if prev is not None:
EqualityConstraint(prev, v, Strength.REQUIRED)
if i == 0:
first = v
if i == n:
last = v
prev = v
StayConstraint(last, Strength.STRONG_DEFAULT)
edit = EditConstraint(first, Strength.PREFERRED)
edits = OrderedCollection()
edits.append(edit)
plan = planner.extract_plan_from_constraints(edits)
for i in range(100):
first.value = i
plan.execute()
if last.value != i:
print("Chain test failed.")
def projection_test(n):
"""
This test constructs a two sets of variables related to each
other by a simple linear transformation (scale and offset). The
time is measured to change a variable on either side of the
mapping and to change the scale and offset factors.
"""
global planner
planner = Planner()
scale = Variable("scale", 10)
offset = Variable("offset", 1000)
src = None
dests = OrderedCollection()
for i in range(n):
src = Variable("src%s" % i, i)
dst = Variable("dst%s" % i, i)
dests.append(dst)
StayConstraint(src, Strength.NORMAL)
ScaleConstraint(src, scale, offset, dst, Strength.REQUIRED)
change(src, 17)
if dst.value != 1170:
print("Projection 1 failed")
change(dst, 1050)
if src.value != 5:
print("Projection 2 failed")
change(scale, 5)
for i in range(n - 1):
if dests[i].value != (i * 5 + 1000):
print("Projection 3 failed")
change(offset, 2000)
for i in range(n - 1):
if dests[i].value != (i * 5 + 2000):
print("Projection 4 failed")
def change(v, new_value):
global planner
edit = EditConstraint(v, Strength.PREFERRED)
edits = OrderedCollection()
edits.append(edit)
plan = planner.extract_plan_from_constraints(edits)
for i in range(10):
v.value = new_value
plan.execute()
edit.destroy_constraint()
# HOORAY FOR GLOBALS... Oh wait.
# In spirit of the original, we'll keep it, but ugh.
planner = None
def delta_blue(n):
chain_test(n)
projection_test(n)
def run_benchmark():
delta_blue(1000)
if __name__ == "__main__":
run_benchmark()
================================================
FILE: benchmarks/benchmarking/cases/deltablue_memray.py
================================================
"""
deltablue.py
============
Ported for the PyPy project.
Contributed by Daniel Lindsley
This implementation of the DeltaBlue benchmark was directly ported
from the `V8's source code`_, which was in turn derived
from the Smalltalk implementation by John Maloney and Mario
Wolczko. The original Javascript implementation was licensed under the GPL.
It's been updated in places to be more idiomatic to Python (for loops over
collections, a couple magic methods, ``OrderedCollection`` being a list & things
altering those collections changed to the builtin methods) but largely retains
the layout & logic from the original. (Ugh.)
.. _`V8's source code`: (https://github.com/v8/v8/blob/master/benchmarks/deltablue.js)
"""
import pyperf
from memray_helper import get_tracker
# The JS variant implements "OrderedCollection", which basically completely
# overlaps with ``list``. So we'll cheat. :D
class OrderedCollection(list):
pass
class Strength(object):
REQUIRED = None
STRONG_PREFERRED = None
PREFERRED = None
STRONG_DEFAULT = None
NORMAL = None
WEAK_DEFAULT = None
WEAKEST = None
def __init__(self, strength, name):
super(Strength, self).__init__()
self.strength = strength
self.name = name
@classmethod
def stronger(cls, s1, s2):
return s1.strength < s2.strength
@classmethod
def weaker(cls, s1, s2):
return s1.strength > s2.strength
@classmethod
def weakest_of(cls, s1, s2):
if cls.weaker(s1, s2):
return s1
return s2
@classmethod
def strongest(cls, s1, s2):
if cls.stronger(s1, s2):
return s1
return s2
def next_weaker(self):
strengths = {
0: self.__class__.WEAKEST,
1: self.__class__.WEAK_DEFAULT,
2: self.__class__.NORMAL,
3: self.__class__.STRONG_DEFAULT,
4: self.__class__.PREFERRED,
# TODO: This looks like a bug in the original code. Shouldn't this be
# ``STRONG_PREFERRED? Keeping for porting sake...
5: self.__class__.REQUIRED,
}
return strengths[self.strength]
# This is a terrible pattern IMO, but true to the original JS implementation.
Strength.REQUIRED = Strength(0, "required")
Strength.STRONG_PREFERRED = Strength(1, "strongPreferred")
Strength.PREFERRED = Strength(2, "preferred")
Strength.STRONG_DEFAULT = Strength(3, "strongDefault")
Strength.NORMAL = Strength(4, "normal")
Strength.WEAK_DEFAULT = Strength(5, "weakDefault")
Strength.WEAKEST = Strength(6, "weakest")
class Constraint(object):
def __init__(self, strength):
super(Constraint, self).__init__()
self.strength = strength
def add_constraint(self):
global planner
self.add_to_graph()
planner.incremental_add(self)
def satisfy(self, mark):
global planner
self.choose_method(mark)
if not self.is_satisfied():
if self.strength == Strength.REQUIRED:
print("Could not satisfy a required constraint!")
return None
self.mark_inputs(mark)
out = self.output()
overridden = out.determined_by
if overridden is not None:
overridden.mark_unsatisfied()
out.determined_by = self
if not planner.add_propagate(self, mark):
print("Cycle encountered")
out.mark = mark
return overridden
def destroy_constraint(self):
global planner
if self.is_satisfied():
planner.incremental_remove(self)
else:
self.remove_from_graph()
def is_input(self):
return False
class UrnaryConstraint(Constraint):
def __init__(self, v, strength):
super(UrnaryConstraint, self).__init__(strength)
self.my_output = v
self.satisfied = False
self.add_constraint()
def add_to_graph(self):
self.my_output.add_constraint(self)
self.satisfied = False
def choose_method(self, mark):
if self.my_output.mark != mark and Strength.stronger(
self.strength, self.my_output.walk_strength
):
self.satisfied = True
else:
self.satisfied = False
def is_satisfied(self):
return self.satisfied
def mark_inputs(self, mark):
# No-ops.
pass
def output(self):
# Ugh. Keeping it for consistency with the original. So much for
# "we're all adults here"...
return self.my_output
def recalculate(self):
self.my_output.walk_strength = self.strength
self.my_output.stay = not self.is_input()
if self.my_output.stay:
self.execute()
def mark_unsatisfied(self):
self.satisfied = False
def inputs_known(self, mark):
return True
def remove_from_graph(self):
if self.my_output is not None:
self.my_output.remove_constraint(self)
self.satisfied = False
class StayConstraint(UrnaryConstraint):
def __init__(self, v, string):
super(StayConstraint, self).__init__(v, string)
def execute(self):
# The methods, THEY DO NOTHING.
pass
class EditConstraint(UrnaryConstraint):
def __init__(self, v, string):
super(EditConstraint, self).__init__(v, string)
def is_input(self):
return True
def execute(self):
# This constraint also does nothing.
pass
class Direction(object):
# Hooray for things that ought to be structs!
NONE = 0
FORWARD = 1
BACKWARD = -1
class BinaryConstraint(Constraint):
def __init__(self, v1, v2, strength):
super(BinaryConstraint, self).__init__(strength)
self.v1 = v1
self.v2 = v2
self.direction = Direction.NONE
self.add_constraint()
def choose_method(self, mark):
if self.v1.mark == mark:
if self.v2.mark != mark and Strength.stronger(
self.strength, self.v2.walk_strength
):
self.direction = Direction.FORWARD
else:
self.direction = Direction.BACKWARD
if self.v2.mark == mark:
if self.v1.mark != mark and Strength.stronger(
self.strength, self.v1.walk_strength
):
self.direction = Direction.BACKWARD
else:
self.direction = Direction.NONE
if Strength.weaker(self.v1.walk_strength, self.v2.walk_strength):
if Strength.stronger(self.strength, self.v1.walk_strength):
self.direction = Direction.BACKWARD
else:
self.direction = Direction.NONE
else:
if Strength.stronger(self.strength, self.v2.walk_strength):
self.direction = Direction.FORWARD
else:
self.direction = Direction.BACKWARD
def add_to_graph(self):
self.v1.add_constraint(self)
self.v2.add_constraint(self)
self.direction = Direction.NONE
def is_satisfied(self):
return self.direction != Direction.NONE
def mark_inputs(self, mark):
self.input().mark = mark
def input(self):
if self.direction == Direction.FORWARD:
return self.v1
return self.v2
def output(self):
if self.direction == Direction.FORWARD:
return self.v2
return self.v1
def recalculate(self):
ihn = self.input()
out = self.output()
out.walk_strength = Strength.weakest_of(self.strength, ihn.walk_strength)
out.stay = ihn.stay
if out.stay:
self.execute()
def mark_unsatisfied(self):
self.direction = Direction.NONE
def inputs_known(self, mark):
i = self.input()
return i.mark == mark or i.stay or i.determined_by is None
def remove_from_graph(self):
if self.v1 is not None:
self.v1.remove_constraint(self)
if self.v2 is not None:
self.v2.remove_constraint(self)
self.direction = Direction.NONE
class ScaleConstraint(BinaryConstraint):
def __init__(self, src, scale, offset, dest, strength):
self.direction = Direction.NONE
self.scale = scale
self.offset = offset
super(ScaleConstraint, self).__init__(src, dest, strength)
def add_to_graph(self):
super(ScaleConstraint, self).add_to_graph()
self.scale.add_constraint(self)
self.offset.add_constraint(self)
def remove_from_graph(self):
super(ScaleConstraint, self).remove_from_graph()
if self.scale is not None:
self.scale.remove_constraint(self)
if self.offset is not None:
self.offset.remove_constraint(self)
def mark_inputs(self, mark):
super(ScaleConstraint, self).mark_inputs(mark)
self.scale.mark = mark
self.offset.mark = mark
def execute(self):
if self.direction == Direction.FORWARD:
self.v2.value = self.v1.value * self.scale.value + self.offset.value
else:
self.v1.value = (self.v2.value - self.offset.value) / self.scale.value
def recalculate(self):
ihn = self.input()
out = self.output()
out.walk_strength = Strength.weakest_of(self.strength, ihn.walk_strength)
out.stay = ihn.stay and self.scale.stay and self.offset.stay
if out.stay:
self.execute()
class EqualityConstraint(BinaryConstraint):
def execute(self):
self.output().value = self.input().value
class Variable(object):
def __init__(self, name, initial_value=0):
super(Variable, self).__init__()
self.name = name
self.value = initial_value
self.constraints = OrderedCollection()
self.determined_by = None
self.mark = 0
self.walk_strength = Strength.WEAKEST
self.stay = True
def __repr__(self):
# To make debugging this beast from pdb easier...
return "<Variable: %s - %s>" % (self.name, self.value)
def add_constraint(self, constraint):
self.constraints.append(constraint)
def remove_constraint(self, constraint):
self.constraints.remove(constraint)
if self.determined_by == constraint:
self.determined_by = None
class Planner(object):
def __init__(self):
super(Planner, self).__init__()
self.current_mark = 0
def incremental_add(self, constraint):
mark = self.new_mark()
overridden = constraint.satisfy(mark)
while overridden is not None:
overridden = overridden.satisfy(mark)
def incremental_remove(self, constraint):
out = constraint.output()
constraint.mark_unsatisfied()
constraint.remove_from_graph()
unsatisfied = self.remove_propagate_from(out)
strength = Strength.REQUIRED
# Do-while, the Python way.
repeat = True
while repeat:
for u in unsatisfied:
if u.strength == strength:
self.incremental_add(u)
strength = strength.next_weaker()
repeat = strength != Strength.WEAKEST
def new_mark(self):
self.current_mark += 1
return self.current_mark
def make_plan(self, sources):
mark = self.new_mark()
plan = Plan()
todo = sources
while len(todo):
c = todo.pop(0)
if c.output().mark != mark and c.inputs_known(mark):
plan.add_constraint(c)
c.output().mark = mark
self.add_constraints_consuming_to(c.output(), todo)
return plan
def extract_plan_from_constraints(self, constraints):
sources = OrderedCollection()
for c in constraints:
if c.is_input() and c.is_satisfied():
sources.append(c)
return self.make_plan(sources)
def add_propagate(self, c, mark):
todo = OrderedCollection()
todo.append(c)
while len(todo):
d = todo.pop(0)
if d.output().mark == mark:
self.incremental_remove(c)
return False
d.recalculate()
self.add_constraints_consuming_to(d.output(), todo)
return True
def remove_propagate_from(self, out):
out.determined_by = None
out.walk_strength = Strength.WEAKEST
out.stay = True
unsatisfied = OrderedCollection()
todo = OrderedCollection()
todo.append(out)
while len(todo):
v = todo.pop(0)
for c in v.constraints:
if not c.is_satisfied():
unsatisfied.append(c)
determining = v.determined_by
for c in v.constraints:
if c != determining and c.is_satisfied():
c.recalculate()
todo.append(c.output())
return unsatisfied
def add_constraints_consuming_to(self, v, coll):
determining = v.determined_by
cc = v.constraints
for c in cc:
if c != determining and c.is_satisfied():
# I guess we're just updating a reference (``coll``)? Seems
# inconsistent with the rest of the implementation, where they
# return the lists...
coll.append(c)
class Plan(object):
def __init__(self):
super(Plan, self).__init__()
self.v = OrderedCollection()
def add_constraint(self, c):
self.v.append(c)
def __len__(self):
return len(self.v)
def __getitem__(self, index):
return self.v[index]
def execute(self):
for c in self.v:
c.execute()
# Main
def chain_test(n):
"""
This is the standard DeltaBlue benchmark. A long chain of equality
constraints is constructed with a stay constraint on one end. An
edit constraint is then added to the opposite end and the time is
measured for adding and removing this constraint, and extracting
and executing a constraint satisfaction plan. There are two cases.
In case 1, the added constraint is stronger than the stay
constraint and values must propagate down the entire length of the
chain. In case 2, the added constraint is weaker than the stay
constraint so it cannot be accomodated. The cost in this case is,
of course, very low. Typical situations lie somewhere between these
two extremes.
"""
global planner
planner = Planner()
prev, first, last = None, None, None
# We need to go up to n inclusively.
for i in range(n + 1):
name = "v%s" % i
v = Variable(name)
if prev is not None:
EqualityConstraint(prev, v, Strength.REQUIRED)
if i == 0:
first = v
if i == n:
last = v
prev = v
StayConstraint(last, Strength.STRONG_DEFAULT)
edit = EditConstraint(first, Strength.PREFERRED)
edits = OrderedCollection()
edits.append(edit)
plan = planner.extract_plan_from_constraints(edits)
for i in range(100):
first.value = i
plan.execute()
if last.value != i:
print("Chain test failed.")
def projection_test(n):
"""
This test constructs a two sets of variables related to each
other by a simple linear transformation (scale and offset). The
time is measured to change a variable on either side of the
mapping and to change the scale and offset factors.
"""
global planner
planner = Planner()
scale = Variable("scale", 10)
offset = Variable("offset", 1000)
src = None
dests = OrderedCollection()
for i in range(n):
src = Variable("src%s" % i, i)
dst = Variable("dst%s" % i, i)
dests.append(dst)
StayConstraint(src, Strength.NORMAL)
ScaleConstraint(src, scale, offset, dst, Strength.REQUIRED)
change(src, 17)
if dst.value != 1170:
print("Projection 1 failed")
change(dst, 1050)
if src.value != 5:
print("Projection 2 failed")
change(scale, 5)
for i in range(n - 1):
if dests[i].value != (i * 5 + 1000):
print("Projection 3 failed")
change(offset, 2000)
for i in range(n - 1):
if dests[i].value != (i * 5 + 2000):
print("Projection 4 failed")
def change(v, new_value):
global planner
edit = EditConstraint(v, Strength.PREFERRED)
edits = OrderedCollection()
edits.append(edit)
plan = planner.extract_plan_from_constraints(edits)
for i in range(10):
v.value = new_value
plan.execute()
edit.destroy_constraint()
# HOORAY FOR GLOBALS... Oh wait.
# In spirit of the original, we'll keep it, but ugh.
planner = None
def delta_blue(n):
chain_test(n)
projection_test(n)
def bench_deltablue(loops, n):
with get_tracker():
t0 = pyperf.perf_counter()
for _ in range(loops):
delta_blue(n)
return pyperf.perf_counter() - t0
if __name__ == "__main__":
runner = pyperf.Runner()
runner.metadata["description"] = "DeltaBlue benchmark"
n = 100
runner.bench_time_func("deltablue", bench_deltablue, n)
================================================
FILE: benchmarks/benchmarking/cases/docutils_data/docs/api/publisher.txt
================================================
========================
The Docutils Publisher
========================
:Author: David Goodger
:Contact: docutils-develop@lists.sourceforge.net
:Date: $Date$
:Revision: $Revision$
:Copyright: This document has been placed in the public domain.
.. contents::
The ``docutils.core.Publisher`` class is the core of Docutils,
managing all the processing and relationships between components. See
`PEP 258`_ for an overview of Docutils components.
The ``docutils.core.publish_*`` convenience functions are the normal
entry points for using Docutils as a library.
See `Inside A Docutils Command-Line Front-End Tool`_ for an overview
of a typical Docutils front-end tool, including how the Publisher
class is used.
.. _PEP 258: ../peps/pep-0258.html
.. _Inside A Docutils Command-Line Front-End Tool: ../howto/cmdline-tool.html
Publisher Convenience Functions
===============================
Each of these functions set up a ``docutils.core.Publisher`` object,
then call its ``publish`` method. ``docutils.core.Publisher.publish``
handles everything else. There are several convenience functions in
the ``docutils.core`` module:
:_`publish_cmdline()`: for command-line front-end tools, like
``rst2html.py``. There are several examples in the ``tools/``
directory. A detailed analysis of one such tool is in `Inside A
Docutils Command-Line Front-End Tool`_
:_`publish_file()`: for programmatic use with file-like I/O. In
addition to writing the encoded output to a file, also returns the
encoded output as a string.
:_`publish_string()`: for programmatic use with string I/O. Returns
the encoded output as a string.
:_`publish_parts()`: for programmatic use with string input; returns a
dictionary of document parts. Dictionary keys are the names of
parts, and values are Unicode strings; encoding is up to the client.
Useful when only portions of the processed document are desired.
See `publish_parts() Details`_ below.
There are usage examples in the `docutils/examples.py`_ module.
:_`publish_doctree()`: for programmatic use with string input; returns a
Docutils document tree data structure (doctree). The doctree can be
modified, pickled & unpickled, etc., and then reprocessed with
`publish_from_doctree()`_.
:_`publish_from_doctree()`: for programmatic use to render from an
existing document tree data structure (doctree); returns the encoded
output as a string.
:_`publish_programmatically()`: for custom programmatic use. This
function implements common code and is used by ``publish_file``,
``publish_string``, and ``publish_parts``. It returns a 2-tuple:
the encoded string output and the Publisher object.
.. _Inside A Docutils Command-Line Front-End Tool: ../howto/cmdline-tool.html
.. _docutils/examples.py: ../../docutils/examples.py
Configuration
-------------
To pass application-specific setting defaults to the Publisher
convenience functions, use the ``settings_overrides`` parameter. Pass
a dictionary of setting names & values, like this::
overrides = {'input_encoding': 'ascii',
'output_encoding': 'latin-1'}
output = publish_string(..., settings_overrides=overrides)
Settings from command-line options override configuration file
settings, and they override application defaults. For details, see
`Docutils Runtime Settings`_. See `Docutils Configuration`_ for
details about individual settings.
.. _Docutils Runtime Settings: ./runtime-settings.html
.. _Docutils Configuration: ../user/config.html
Encodings
---------
The default output encoding of Docutils is UTF-8.
Docutils may introduce some non-ASCII text if you use
`auto-symbol footnotes`_ or the `"contents" directive`_.
.. _auto-symbol footnotes:
../ref/rst/restructuredtext.html#auto-symbol-footnotes
.. _"contents" directive:
../ref/rst/directives.html#table-of-contents
``publish_parts()`` Details
===========================
The ``docutils.core.publish_parts()`` convenience function returns a
dictionary of document parts. Dictionary keys are the names of parts,
and values are Unicode strings.
Each Writer component may publish a different set of document parts,
described below. Not all writers implement all parts.
Parts Provided By All Writers
-----------------------------
_`encoding`
The output encoding setting.
_`version`
The version of Docutils used.
_`whole`
``parts['whole']`` contains the entire formatted document.
Parts Provided By the HTML Writers
----------------------------------
HTML4 Writer
````````````
_`body`
``parts['body']`` is equivalent to parts['fragment_']. It is
*not* equivalent to parts['html_body_'].
_`body_prefix`
``parts['body_prefix']`` contains::
</head>
<body>
<div class="document" ...>
and, if applicable::
<div class="header">
...
</div>
_`body_pre_docinfo`
``parts['body_pre_docinfo]`` contains (as applicable)::
<h1 class="title">...</h1>
<h2 class="subtitle" id="...">...</h2>
_`body_suffix`
``parts['body_suffix']`` contains::
</div>
(the end-tag for ``<div class="document">``), the footer division
if applicable::
<div class="footer">
...
</div>
and::
</body>
</html>
_`docinfo`
``parts['docinfo']`` contains the document bibliographic data, the
docinfo field list rendered as a table.
_`footer`
``parts['footer']`` contains the document footer content, meant to
appear at the bottom of a web page, or repeated at the bottom of
every printed page.
_`fragment`
``parts['fragment']`` contains the document body (*not* the HTML
``<body>``). In other words, it contains the entire document,
less the document title, subtitle, docinfo, header, and footer.
_`head`
``parts['head']`` contains ``<meta ... />`` tags and the document
``<title>...</title>``.
_`head_prefix`
``parts['head_prefix']`` contains the XML declaration, the DOCTYPE
declaration, the ``<html ...>`` start tag and the ``<head>`` start
tag.
_`header`
``parts['header']`` contains the document header content, meant to
appear at the top of a web page, or repeated at the top of every
printed page.
_`html_body`
``parts['html_body']`` contains the HTML ``<body>`` content, less
the ``<body>`` and ``</body>`` tags themselves.
_`html_head`
``parts['html_head']`` contains the HTML ``<head>`` content, less
the stylesheet link and the ``<head>`` and ``</head>`` tags
themselves. Since ``publish_parts`` returns Unicode strings and
does not know about the output encoding, the "Content-Type" meta
tag's "charset" value is left unresolved, as "%s"::
<meta http-equiv="Content-Type" content="text/html; charset=%s" />
The interpolation should be done by client code.
_`html_prolog`
``parts['html_prolog]`` contains the XML declaration and the
doctype declaration. The XML declaration's "encoding" attribute's
value is left unresolved, as "%s"::
<?xml version="1.0" encoding="%s" ?>
The interpolation should be done by client code.
_`html_subtitle`
``parts['html_subtitle']`` contains the document subtitle,
including the enclosing ``<h2 class="subtitle">`` & ``</h2>``
tags.
_`html_title`
``parts['html_title']`` contains the document title, including the
enclosing ``<h1 class="title">`` & ``</h1>`` tags.
_`meta`
``parts['meta']`` contains all ``<meta ... />`` tags.
_`stylesheet`
``parts['stylesheet']`` contains the embedded stylesheet or
stylesheet link.
_`subtitle`
``parts['subtitle']`` contains the document subtitle text and any
inline markup. It does not include the enclosing ``<h2>`` &
``</h2>`` tags.
_`title`
``parts['title']`` contains the document title text and any inline
markup. It does not include the enclosing ``<h1>`` & ``</h1>``
tags.
PEP/HTML Writer
```````````````
The PEP/HTML writer provides the same parts as the `HTML4 writer`_,
plus the following:
_`pepnum`
``parts['pepnum']`` contains
S5/HTML Writer
``````````````
The S5/HTML writer provides the same parts as the `HTML4 writer`_.
HTML5 Writer
````````````
The HTML5 writer provides the same parts as the `HTML4 writer`_.
However, it uses semantic HTML5 elements for the document, header and
footer.
Parts Provided by the LaTeX2e Writer
------------------------------------
See the template files for examples how these parts can be combined
into a valid LaTeX document.
abstract
``parts['abstract']`` contains the formatted content of the
'abstract' docinfo field.
body
``parts['body']`` contains the document's content. In other words, it
contains the entire document, except the document title, subtitle, and
docinfo.
This part can be included into another LaTeX document body using the
``\input{}`` command.
body_pre_docinfo
``parts['body_pre_docinfo]`` contains the ``\maketitle`` command.
dedication
``parts['dedication']`` contains the formatted content of the
'dedication' docinfo field.
docinfo
``parts['docinfo']`` contains the document bibliographic data, the
docinfo field list rendered as a table.
With ``--use-latex-docinfo`` 'author', 'organization', 'contact',
'address' and 'date' info is moved to titledata.
'dedication' and 'abstract' are always moved to separate parts.
fallbacks
``parts['fallbacks']`` contains fallback definitions for
Docutils-specific commands and environments.
head_prefix
``parts['head_prefix']`` contains the declaration of
documentclass and document options.
latex_preamble
``parts['latex_preamble']`` contains the argument of the
``--latex-preamble`` option.
pdfsetup
``parts['pdfsetup']`` contains the PDF properties
("hyperref" package setup).
requirements
``parts['requirements']`` contains required packages and setup
before the stylesheet inclusion.
stylesheet
``parts['stylesheet']`` contains the embedded stylesheet(s) or
stylesheet loading command(s).
subtitle
``parts['subtitle']`` contains the document subtitle text and any
inline markup.
title
``parts['title']`` contains the document title text and any inline
markup.
titledata
``parts['titledata]`` contains the combined title data in
``\title``, ``\author``, and ``\data`` macros.
With ``--use-latex-docinfo``, this includes the 'author',
'organization', 'contact', 'address' and 'date' docinfo items.
================================================
FILE: benchmarks/benchmarking/cases/docutils_data/docs/api/runtime-settings.txt
================================================
===========================
Docutils Runtime Settings
===========================
:Author: David Goodger, Günter Milde
:Contact: docutils-develop@lists.sourceforge.net
:Date: $Date$
:Revision: $Revision$
:Copyright: This document has been placed in the public domain.
.. contents::
Introduction
============
Docutils runtime settings are assembled from several sources:
* Settings specifications of the selected components_,
* `configuration files`_ (if enabled), and
* command-line options (if enabled).
Docutils overlays default and explicitly specified values from these
sources such that settings behave the way we want and expect them to
behave.
Settings priority
=================
The sources are overlaid in the following order (later sources
overwrite earlier ones):
1. Defaults specified in the `settings_spec`__ and
`settings_defaults`__ attributes for each component_.
__ SettingsSpec.settings_spec_
__ SettingsSpec.settings_defaults_
2. Defaults specified in the `settings_default_overrides`__ attribute
for each component_.
__ SettingsSpec.settings_default_overrides_
3. Settings specified in the `settings_overrides`__ parameter of the
`convenience functions`_ resp. the `settings_overrides` attribute of
a `Publisher`_ instance.
__ `settings_overrides parameter`_
4. Settings specified in `active sections`_ of the `configuration files`_
in the order described in `Configuration File Sections & Entries`_
(if enabled).
5. Command line options (if enabled).
For details see the ``docutils/__init__.py``, ``docutils/core.py``, and
``docutils.frontend.py`` modules and the implementation description in
`Runtime Settings Processing`_.
.. _SettingsSpec:
SettingsSpec base class
=======================
.. note::
Implementation details will change with the move to replace the
deprecated optparse_ module with argparse_.
The `docutils.SettingsSpec` base class is inherited by Docutils
components_ and `frontend.OptionParser`.
It defines the following six **attributes**:
.. _SettingsSpec.settings_spec:
`settings_spec`
a sequence of
1. option group title (string or None)
2. description (string or None)
3. option tuples with
a) help text
b) options string(s)
c) dictionary with keyword arguments for `OptionParser.add_option()`_
and an optional "validator", a `frontend.validate_*()` function
that processes the values (e.g. convert to other data types).
For examples, see the source of ``frontend.OptionParser.settings_spec``
or the `settings_spec` attributes of the Docutils components_.
.. _SettingsSpec.settings_defaults:
`settings_defaults`
for purely programmatic settings
(not accessible from command line and configuration files).
.. _SettingsSpec.settings_default_overrides:
`settings_default_overrides`
to override defaults for settings
defined in other components' `setting_specs`.
`relative_path_settings`
listing settings containing filesystem paths.
.. _active sections:
`config_section`
the configuration file section specific to this
component.
`config_section_dependencies`
lists configuration files sections
that should also be read (before the `config_section`).
The last two attributes define which configuration file sections are
"active". See also `Configuration File Sections & Entries`_.
Glossary
========
.. _component:
components
----------
Docutils front-ends and applications combine a selection of
*components* of the `Docutils Project Model`_.
All components inherit the `SettingsSpec`_ base class.
This means that all instances of ``readers.Reader``, ``parsers.Parser``, and
``writers.Writer`` are also instances of ``docutils.SettingsSpec``.
For the determination of runtime settings, ``frontend.OptionParser`` and
the `settings_spec parameter`_ in application settings specifications
are treated as components as well.
.. _convenience function:
convenience functions
---------------------
Applications usually deploy Docutils by one of the
`Publisher convenience functions`_.
All convenience functions accept the following optional parameters:
.. _settings parameter:
`settings`
a ``frontend.Values`` instance.
If present, it must be complete.
No further runtime settings processing is done and the
following parameters have no effect.
.. _settings_spec parameter:
`settings_spec`
a `SettingsSpec`_ subclass or instance containing the settings
specification for the "Application" itself.
The instance is added to the components_ (after the generic
settings, parser, reader, and writer).
.. _settings_overrides parameter:
`settings_overrides`
a dictionary which is used to update the
defaults of the components' settings specifications.
.. _config_section parameter:
`config_section`
the name of an application-specific
`configuration file section`_ for this application.
Can be specified instead of a `settings_spec` (a new SettingsSpec_
instance that just defines a configuration section will be created)
or in addition to a `settings_spec`
(overriding its `config_section` attribute).
settings_spec
-------------
The name ``settings_spec`` may refer to
a) an instance of the SettingsSpec_ class, or
b) the data structure `SettingsSpec.settings_spec`_ which is used to
store settings details.
.. References:
.. _Publisher: publisher.html
.. _Publisher convenience functions:
publisher.html#publisher-convenience-functions
.. _front-end tools: ../user/tools.html
.. _configuration files:
.. _Docutils Configuration: ../user/config.html#configuration-files
.. _configuration file section:
.. _Configuration File Sections & Entries:
../user/config.html#configuration-file-sections-entries
.. _Docutils Project Model: ../peps/pep-0258.html#docutils-project-model
.. _Reader: ../peps/pep-0258.html#reader
.. _Runtime Settings Processing: ../dev/runtime-settings-processing.html
.. _optparse: https://docs.python.org/dev/library/optparse.html
.. _argparse: https://docs.python.org/dev/library/argparse.html
.. _OptionParser.add_option():
https://docs.python.org/dev/library/optparse.html
#optparse.OptionParser.add_option
================================================
FILE: benchmarks/benchmarking/cases/docutils_data/docs/api/transforms.txt
================================================
=====================
Docutils Transforms
=====================
:Author: David Goodger
:Contact: docutils-develop@lists.sourceforge.net
:Revision: $Revision$
:Date: $Date$
:Copyright: This document has been placed in the public domain.
.. contents::
Transforms change the document tree in-place, add to the tree, or prune it.
Transforms resolve references and footnote numbers, process interpreted
text, and do other context-sensitive processing. Each transform is a
subclass of ``docutils.transforms.Transform``.
There are `transforms added by components`_, others (e.g.
``parts.Contents``) are added by the parser, if a corresponding directive is
found in the document.
To add a transform, components (objects inheriting from
Docutils.Component like Readers, Parsers, Writers, Input, Output) overwrite
the ``get_transforms()`` method of their base class. After the Reader has
finished processing, the Publisher calls
``Transformer.populate_from_components()`` with a list of components and all
transforms returned by the component's ``get_transforms()`` method are
stored in a `transformer object` attached to the document tree.
For more about transforms and the Transformer object, see also `PEP
258`_. (The ``default_transforms()`` attribute of component classes mentioned
there is deprecated. Use the ``get_transforms()`` method instead.)
.. _PEP 258: ../peps/pep-0258.html#transformer
Transforms Listed in Priority Order
===================================
Transform classes each have a default_priority attribute which is used by
the Transformer to apply transforms in order (low to high). The default
priority can be overridden when adding transforms to the Transformer object.
============================== ============================ ========
Transform: module.Class Added By Priority
============================== ============================ ========
misc.class "class" (d/p) 210
references.Substitutions standalone (r), pep (r) 220
references.PropagateTargets standalone (r), pep (r) 260
frontmatter.DocTitle standalone (r) 320
frontmatter.DocInfo standalone (r) 340
frontmatter.SectSubTitle standalone (r) 350
peps.Headers pep (r) 360
peps.Contents pep (r) 380
universal.StripClasses... Writer (w) 420
references.AnonymousHyperlinks standalone (r), pep (r) 440
references.IndirectHyperlinks standalone (r), pep (r) 460
peps.TargetNotes pep (r) 520
references.TargetNotes peps.TargetNotes (t/p) 0
misc.CallBack peps.TargetNotes (t/p) 1
references.TargetNotes "target-notes" (d/p) 540
references.Footnotes standalone (r), pep (r) 620
references.ExternalTargets standalone (r), pep (r) 640
references.InternalTargets standalone (r), pep (r) 660
parts.SectNum "sectnum" (d/p) 710
parts.Contents "contents" (d/p), 720
peps.Contents (t/p)
universal.StripComments Reader (r) 740
peps.PEPZero peps.Headers (t/p) 760
components.Filter *not used* 780
universal.Decorations Reader (r) 820
misc.Transitions standalone (r), pep (r) 830
universal.ExposeInternals Reader (r) 840
references.DanglingReferences standalone (r), pep (r) 850
universal.SmartQuotes Parser 855
universal.Messages Writer (w) 860
universal.FilterMessages Writer (w) 870
universal.TestMessages DocutilsTestSupport 880
writer_aux.Compound *not used, to be removed* 910
writer_aux.Admonitions html4css1 (w), 920
latex2e (w)
misc.CallBack n/a 990
============================== ============================ ========
Key:
* (r): Reader
* (w): Writer
* (d): Directive
* (t): Transform
* (/p): Via a "pending" node
Transform Priority Range Categories
===================================
==== ==== ================================================
Priority
---------- ------------------------------------------------
From To Category
==== ==== ================================================
0 99 immediate execution (added by another transform)
100 199 very early (non-standard)
200 299 very early
300 399 early
400 699 main
700 799 late
800 899 very late
900 999 very late (non-standard)
==== ==== ================================================
Transforms added by components
===============================
readers.Reader:
| universal.Decorations,
| universal.ExposeInternals,
| universal.StripComments
readers.ReReader:
None
readers.standalone.Reader:
| references.Substitutions,
| references.PropagateTargets,
| frontmatter.DocTitle,
| frontmatter.SectionSubTitle,
| frontmatter.DocInfo,
| references.AnonymousHyperlinks,
| references.IndirectHyperlinks,
| references.Footnotes,
| references.ExternalTargets,
| references.InternalTargets,
| references.DanglingReferences,
| misc.Transitions
readers.pep.Reader:
| references.Substitutions,
| references.PropagateTargets,
| references.AnonymousHyperlinks,
| references.IndirectHyperlinks,
| references.Footnotes,
| references.ExternalTargets,
| references.InternalTargets,
| references.DanglingReferences,
| misc.Transitions,
| peps.Headers,
| peps.Contents,
| peps.TargetNotes
parsers.rst.Parser
universal.SmartQuotes
writers.Writer:
| universal.Messages,
| universal.FilterMessages,
| universal.StripClassesAndElements
writers.UnfilteredWriter
None
writers.latex2e.Writer
writer_aux.Admonitions
writers.html4css1.Writer:
writer_aux.Admonitions
writers.odf_odt.Writer:
removes references.DanglingReferences
================================================
FILE: benchmarks/benchmarking/cases/docutils_data/docs/dev/distributing.txt
================================================
===============================
Docutils_ Distributor's Guide
===============================
:Author: Lea Wiemann
:Contact: docutils-develop@lists.sourceforge.net
:Revision: $Revision$
:Date: $Date$
:Copyright: This document has been placed in the public domain.
.. _Docutils: https://docutils.sourceforge.io/
.. contents::
This document describes how to create packages of Docutils (e.g. for
shipping with a Linux distribution). If you have any questions,
please direct them to the Docutils-develop_ mailing list.
First, please download the most current `release tarball`_ and unpack
it.
.. _Docutils-develop: ../user/mailing-lists.html#docutils-develop
.. _release tarball: https://docutils.sourceforge.io/#download
Dependencies
============
Docutils has the following dependencies:
* Python 3.7 or later is required.
Use ">= Python 3.7" in the dependencies.
* Docutils may optionally make use of the PIL (`Python Imaging
Library`_ or Pillow_). If PIL is present, it is automatically
detected by Docutils.
* Docutils recommends the `Pygments`_ syntax hightlighter. If available, it
is used for highlighting the content of `code directives`_ and roles as
well as included source code files (with the "code" option to the include_
directive).
* Docutils can use the `recommonmark`_ parser to parse input in
the Markdown format (new in 0.17).
.. _Python Imaging Library:
https://en.wikipedia.org/wiki/Python_Imaging_Library
.. _Pillow: https://pypi.org/project/Pillow/
.. _Pygments: https://pygments.org/
.. _recommonmark: https://pypi.org/project/recommonmark/
.. _code directives: ../ref/rst/directives.html#code
.. _include: ../ref/rst/directives.html#include
Python Files
============
The Docutils Python files must be installed into the
``site-packages/`` directory of Python. Running ``python setup.py
install`` should do the trick, but if you want to place the files
yourself, you can just install the ``docutils/`` directory of the
Docutils tarball to ``/usr/lib/python/site-packages/docutils/``. In
this case you should also compile the Python files to ``.pyc`` and/or
``.pyo`` files so that Docutils doesn't need to be recompiled every
time it's executed.
Executables
===========
The executable front-end tools are located in the ``tools/`` directory
of the Docutils tarball.
The ``rst2*.py`` tools are intended for end-users. You should install them
to ``/usr/bin/``. You do not need to change the names (e.g. to
``docutils-rst2html.py``) because the ``rst2`` prefix is unique.
Documentation
=============
The documentation should be generated using ``buildhtml.py``. To
generate HTML for all documentation files, go to the ``tools/``
directory and run::
# Place html4css1.css in base directory.
cp ../docutils/writers/html4css1/html4css1.css ..
./buildhtml.py --stylesheet-path=../html4css1.css ..
Then install the following files to ``/usr/share/doc/docutils/`` (or
wherever you install documentation):
* All ``.html`` and ``.txt`` files in the base directory.
* The ``docs/`` directory.
Do not install the contents of the ``docs/`` directory directly to
``/usr/share/doc/docutils/``; it's incomplete and would contain
invalid references!
* The ``licenses/`` directory.
* ``html4css1.css`` in the base directory.
Removing the ``.txt`` Files
---------------------------
If you are tight with disk space, you can remove all ``.txt`` files in
the tree except for:
* those in the ``licenses/`` directory because they have not been
processed to HTML and
* ``user/rst/cheatsheet.txt`` and ``user/rst/demo.txt``, which should
be readable in source form.
Before you remove the ``.txt`` files you should rerun ``buildhtml.py``
with the ``--no-source-link`` switch to avoid broken references to the
source files.
Other Files
===========
You may want to install the Emacs-Lisp files
``tools/editors/emacs/*.el`` into the appropriate directory.
Configuration File
==================
It is possible to have a system-wide configuration file at
``/etc/docutils.conf``. However, this is usually not necessary. You
should *not* install ``tools/docutils.conf`` into ``/etc/``.
Tests
=====
While you probably do not need to ship the tests with your
distribution, you can test your package by installing it and then
running ``alltests.py`` from the ``tests/`` directory of the Docutils
tarball.
For more information on testing, view the `Docutils Testing`_ page.
.. _Docutils Testing: https://docutils.sourceforge.io/docs/dev/testing.html
================================================
FILE: benchmarks/benchmarking/cases/docutils_data/docs/dev/enthought-plan.txt
================================================
===========================================
Plan for Enthought API Documentation Tool
===========================================
:Author: David Goodger
:Contact: docutils-develop@lists.sourceforge.net
:Date: $Date$
:Revision: $Revision$
:Copyright: 2004 by `Enthought, Inc. <http://www.enthought.com>`_
:License: `Enthought License`_ (BSD-style)
.. _Enthought License: https://docutils.sourceforge.io/licenses/enthought.txt
This document should be read in conjunction with the `Enthought API
Documentation Tool RFP`__ prepared by Janet Swisher.
__ enthought-rfp.html
.. contents::
.. sectnum::
Introduction
============
In March 2004 at I met Eric Jones, president and CTO of `Enthought,
Inc.`_, at `PyCon 2004`_ in Washington DC. He told me that Enthought
was using reStructuredText_ for source code documentation, but they
had some issues. He asked if I'd be interested in doing some work on
a customized API documentation tool. Shortly after PyCon, Janet
Swisher, Enthought's senior technical writer, contacted me to work out
details. Some email, a trip to Austin in May, and plenty of Texas
hospitality later, we had a project. This document will record the
details, milestones, and evolution of the project.
In a nutshell, Enthought is sponsoring the implementation of an open
source API documentation tool that meets their needs. Fortuitously,
their needs coincide well with the "Python Source Reader" description
in `PEP 258`_. In other words, Enthought is funding some significant
improvements to Docutils, improvements that were planned but never
implemented due to time and other constraints. The implementation
will take place gradually over several months, on a part-time basis.
This is an ideal example of cooperation between a corporation and an
open-source project. The corporation, the project, I personally, and
the community all benefit. Enthought, whose commitment to open source
is also evidenced by their sponsorship of SciPy_, benefits by
obtaining a useful piece of software, much more quickly than would
have been possible without their support. Docutils benefits directly
from the implementation of one of its core subsystems. I benefit from
the funding, which allows me to justify the long hours to my wife and
family. All the corporations, projects, and individuals that make up
the community will benefit from the end result, which will be great.
All that's left now is to actually do the work!
.. _PyCon 2004: http://pycon.org/dc2004/
.. _reStructuredText: https://docutils.sourceforge.io/rst.html
.. _SciPy: http://www.scipy.org/
Development Plan
================
1. Analyze prior art, most notably Epydoc_ and HappyDoc_, to see how
they do what they do. I have no desire to reinvent wheels
unnecessarily. I want to take the best ideas from each tool,
combined with the outline in `PEP 258`_ (which will evolve), and
build at least the foundation of the definitive Python
auto-documentation tool.
.. _Epydoc: http://epydoc.sourceforge.net/
.. _HappyDoc: http://happydoc.sourceforge.net/
.. _PEP 258:
https://docutils.sourceforge.io/docs/peps/pep-0258.html#python-source-reader
2. Decide on a base platform. The best way to achieve Enthought's
goals in a reasonable time frame may be to extend Epydoc or
HappyDoc. Or it may be necessary to start fresh.
3. Extend the reStructuredText parser. See `Proposed Changes to
reStructuredText`_ below.
4. Depending on the base platform chosen, build or extend the
docstring & doc comment extraction tool. This may be the biggest
part of the project, but I won't be able to break it down into
details until more is known.
Repository
==========
If possible, all software and documentation files will be stored in
the Subversion repository of Docutils and/or the base project, which
are all publicly-available via anonymous pserver access.
The Docutils project is very open about granting Subversion write
access; so far, everyone who asked has been given access. Any
Enthought staff member who would like Subversion write access will get
it.
If either Epydoc or HappyDoc is chosen as the base platform, I will
ask the project's administrator for CVS access for myself and any
Enthought staff member who wants it. If sufficient access is not
granted -- although I doubt that there would be any problem -- we may
have to begin a fork, which could be hosted on SourceForge, on
Enthought's Subversion server, or anywhere else deemed appropriate.
Copyright & License
===================
Most existing Docutils files have been placed in the public domain, as
follows::
:Copyright: This document has been placed in the public domain.
This is in conjunction with the "Public Domain Dedication" section of
COPYING.txt__.
__ https://docutils.sourceforge.io/COPYING.html
The code and documentation originating from Enthought funding will
have Enthought's copyright and license declaration. While I will try
to keep Enthought-specific code and documentation separate from the
existing files, there will inevitably be cases where it makes the most
sense to extend existing files.
I propose the following:
1. New files related to this Enthought-funded work will be identified
with the following field-list headers::
:Copyright: 2004 by Enthought, Inc.
:License: Enthought License (BSD Style)
The license field text will be linked to the license file itself.
2. For significant or major changes to an existing file (more than 10%
change), the headers shall change as follows (for example)::
:Copyright: 2001-2004 by David Goodger
:Copyright: 2004 by Enthought, Inc.
:License: BSD-style
If the Enthought-funded portion becomes greater than the previously
existing portion, Enthought's copyright line will be shown first.
3. In cases of insignificant or minor changes to an existing file
(less than 10% change), the public domain status shall remain
unchanged.
A section describing all of this will be added to the Docutils
`COPYING`__ instructions file.
If another project is chosen as the base project, similar changes
would be made to their files, subject to negotiation.
__ https://docutils.sourceforge.io/COPYING.html
Proposed Changes to reStructuredText
====================================
Doc Comment Syntax
------------------
The "traits" construct is implemented as dictionaries, where
standalone strings would be Python syntax errors. Therefore traits
require documentation in comments. We also need a way to
differentiate between ordinary "internal" comments and documentation
comments (doc comments).
Javadoc uses the following syntax for doc comments::
/**
* The first line of a multi-line doc comment begins with a slash
* and *two* asterisks. The doc comment ends normally.
*/
Python doesn't have multi-line comments; only single-line. A similar
convention in Python might look like this::
##
# The first line of a doc comment begins with *two* hash marks.
# The doc comment ends with the first non-comment line.
'data' : AnyValue,
## The double-hash-marks could occur on the first line of text,
# saving a line in the source.
'data' : AnyValue,
How to indicate the end of the doc comment? ::
##
# The first line of a doc comment begins with *two* hash marks.
# The doc comment ends with the first non-comment line, or another
# double-hash-mark.
##
# This is an ordinary, internal, non-doc comment.
'data' : AnyValue,
## First line of a doc comment, terse syntax.
# Second (and last) line. Ends here: ##
# This is an ordinary, internal, non-doc comment.
'data' : AnyValue,
Or do we even need to worry about this case? A simple blank line
could be used::
## First line of a doc comment, terse syntax.
# Second (and last) line. Ends with a blank line.
# This is an ordinary, internal, non-doc comment.
'data' : AnyValue,
Other possibilities::
#" Instead of double-hash-marks, we could use a hash mark and a
# quotation mark to begin the doc comment.
'data' : AnyValue,
## We could require double-hash-marks on every line. This has the
## added benefit of delimiting the *end* of the doc comment, as
## well as working well with line wrapping in Emacs
## ("fill-paragraph" command).
# Ordinary non-doc comment.
'data' : AnyValue,
#" A hash mark and a quotation mark on each line looks funny, and
#" it doesn't work well with line wrapping in Emacs.
'data' : AnyValue,
These styles (repeated on each line) work well with line wrapping in
Emacs::
## #> #| #- #% #! #*
These styles do *not* work well with line wrapping in Emacs::
#" #' #: #) #. #/ #@ #$ #^ #= #+ #_ #~
The style of doc comment indicator used could be a runtime, global
and/or per-module setting. That may add more complexity than it's
worth though.
Recommendation
``````````````
I recommend adopting "#*" on every line::
# This is an ordinary non-doc comment.
#* This is a documentation comment, with an asterisk after the
#* hash marks on every line.
'data' : AnyValue,
I initially recommended adopting double-hash-marks::
# This is an ordinary non-doc comment.
## This is a documentation comment, with double-hash-marks on
## every line.
'data' : AnyValue,
But Janet Swisher rightly pointed out that this could collide with
ordinary comments that are then block-commented. This applies to
double-hash-marks on the first line only as well. So they're out.
On the other hand, the JavaDoc-comment style ("##" on the first line
only, "#" after that) is used in Fredrik Lundh's PythonDoc_. It may
be worthwhile to conform to this syntax, reinforcing it as a standard.
PythonDoc does not support terse doc comments (text after "##" on the
first line).
.. _PythonDoc: http://effbot.org/zone/pythondoc.htm
Update
``````
Enthought's Traits system has switched to a metaclass base, and traits
are now defined via ordinary attributes. Therefore doc comments are
no longer absolutely necessary; attribute docstrings will suffice.
Doc comments may still be desirable though, since they allow
documentation to precede the thing being documented.
Docstring Density & Whitespace Minimization
-------------------------------------------
One problem with extensively documented classes & functions, is that
there is a lot of screen space wasted on whitespace. Here's some
current Enthought code (from lib/cp/fluids/gassmann.py)::
def max_gas(temperature, pressure, api, specific_gravity=.56):
"""
Computes the maximum dissolved gas in oil using Batzle and
Wang (1992).
Parameters
----------
temperature : sequence
Temperature in degrees Celsius
pressure : sequence
Pressure in MPa
api : sequence
Stock tank oil API
specific_gravity : sequence
Specific gravity of gas at STP, default is .56
Returns
-------
max_gor : sequence
Maximum dissolved gas in liters/liter
Description
-----------
This estimate is based on equations given by Mavko, Mukerji,
and Dvorkin, (1998, pp. 218-219, or 2003, p. 236) obtained
originally from Batzle and Wang (1992).
"""
code...
The docstring is 24 lines long.
Rather than using subsections, field lists (which exist now) can save
6 lines::
def max_gas(temperature, pressure, api, specific_gravity=.56):
"""
Computes the maximum dissolved gas in oil using Batzle and
Wang (1992).
:Parameters:
temperature : sequence
Temperature in degrees Celsius
pressure : sequence
Pressure in MPa
api : sequence
Stock tank oil API
specific_gravity : sequence
Specific gravity of gas at STP, default is .56
:Returns:
max_gor : sequence
Maximum dissolved gas in liters/liter
:Description: This estimate is based on equations given by
Mavko, Mukerji, and Dvorkin, (1998, pp. 218-219, or 2003,
p. 236) obtained originally from Batzle and Wang (1992).
"""
code...
As with the "Description" field above, field bodies may begin on the
same line as the field name, which also saves space.
The output for field lists is typically a table structure. For
example:
:Parameters:
temperature : sequence
Temperature in degrees Celsius
pressure : sequence
Pressure in MPa
api : sequence
Stock tank oil API
specific_gravity : sequence
Specific gravity of gas at STP, default is .56
:Returns:
max_gor : sequence
Maximum dissolved gas in liters/liter
:Description:
This estimate is based on equations given by Mavko,
Mukerji, and Dvorkin, (1998, pp. 218-219, or 2003, p. 236)
obtained originally from Batzle and Wang (1992).
But the definition lists describing the parameters and return values
are still wasteful of space. There are a lot of half-filled lines.
Definition lists are currently defined as::
term : classifier
definition
Where the classifier part is optional. Ideas for improvements:
1. We could allow multiple classifiers::
term : classifier one : two : three ...
definition
2. We could allow the definition on the same line as the term, using
some embedded/inline markup:
* "--" could be used, but only in limited and well-known contexts::
term -- definition
This is the syntax used by StructuredText (one of
reStructuredText's predecessors). It was not adopted for
reStructuredText because it is ambiguous -- people often use "--"
in their text, as I just did. But given a constrained context,
the ambiguity would be acceptable (or would it?). That context
would be: in docstrings, within a field list, perhaps only with
certain well-defined field names (parameters, returns).
* The "constrained context" above isn't really enough to make the
ambiguity acceptable. Instead, a slightly more verbose but far
less ambiguous syntax is possible::
term === definition
This syntax has advantages. Equals signs lend themselves to the
connotation of "definition". And whereas one or two equals signs
are commonly used in program code, three equals signs in a row
have no conflicting meanings that I know of. (Update: there
*are* uses out there.)
The problem with this approach is that using inline markup for
structure is inherently ambiguous in reStructuredText. For
example, writing *about* definition lists would be difficult::
``term === definition`` is an example of a compact definition list item
The parser checks for structural markup before it does inline
markup processing. But the "===" should be protected by its inline
literal context.
3. We could allow the definition on the same line as the term, using
structural markup. A variation on bullet lists would work well::
: term :: definition
: another term :: and a definition that
wraps across lines
Some ambiguity remains::
: term ``containing :: double colons`` :: definition
But the likelihood of such cases is negligible, and they can be
covered in the documentation.
Other possibilities for the definition delimiter include::
: term : classifier -- definition
: term : classifier --- definition
: term : classifier : : definition
: term : classifier === definition
The third idea currently has the best chance of being adopted and
implemented.
Recommendation
``````````````
Combining these ideas, the function definition becomes::
def max_gas(temperature, pressure, api, specific_gravity=.56):
"""
Computes the maximum dissolved gas in oil using Batzle and
Wang (1992).
:Parameters:
: temperature : sequence :: Temperature in degrees Celsius
: pressure : sequence :: Pressure in MPa
: api : sequence :: Stock tank oil API
: specific_gravity : sequence :: Specific gravity of gas at
STP, default is .56
:Returns:
: max_gor : sequence :: Maximum dissolved gas in liters/liter
:Description: This estimate is based on equations given by
Mavko, Mukerji, and Dvorkin, (1998, pp. 218-219, or 2003,
p. 236) obtained originally from Batzle and Wang (1992).
"""
code...
The docstring is reduced to 14 lines, from the original 24. For
longer docstrings with many parameters and return values, the
difference would be more significant.
================================================
FILE: benchmarks/benchmarking/cases/docutils_data/docs/dev/enthought-rfp.txt
================================================
==================================
Enthought API Documentation Tool
==================================
-----------------------
Request for Proposals
-----------------------
:Author: Janet Swisher, Senior Technical Writer
:Organization: `Enthought, Inc. <http://www.enthought.com>`_
:Copyright: 2004 by Enthought, Inc.
:License: `Enthought License`_ (BSD Style)
.. _Enthought License: https://docutils.sourceforge.io/licenses/enthought.txt
The following is excerpted from the full RFP, and is published here
with permission from `Enthought, Inc.`_ See the `Plan for Enthought
API Documentation Tool`__.
__ enthought-plan.html
.. contents::
.. sectnum::
Requirements
============
The documentation tool will address the following high-level goals:
Documentation Extraction
------------------------
1. Documentation will be generated directly from Python source code,
drawing from the code structure, docstrings, and possibly other
comments.
2. The tool will extract logical constructs as appropriate, minimizing
the need for comments that are redundant with the code structure.
The output should reflect both documented and undocumented
elements.
Source Format
-------------
1. The docstrings will be formatted in as terse syntax as possible.
Required tags, syntax, and white space should be minimized.
2. The tool must support the use of Traits. Special comment syntax
for Traits may be necessary. Information about the Traits package
is available at http://code.enthought.com/traits/. In the
following example, each trait definition is prefaced by a plain
comment::
__traits__ = {
# The current selection within the frame.
'selection' : Trait([], TraitInstance(list)),
# The frame has been activated or deactivated.
'activated' : TraitEvent(),
'closing' : TraitEvent(),
# The frame is closed.
'closed' : TraitEvent(),
}
3. Support for ReStructuredText (ReST) format is desirable, because
much of the existing docstrings uses ReST. However, the complete
ReST specification need not be supported, if a subset can achieve
the project goals. If the tool does not support ReST, the
contractor should also provide a tool or path to convert existing
docstrings.
Output Format
-------------
1. Documentation will be output as a navigable suite of HTML
files.
2. The style of the HTML files will be customizable by a cascading
style sheet and/or a customizable template.
3. Page elements such as headers and footer should be customizable, to
support differing requirements from one documentation project to
the next.
Output Structure and Navigation
-------------------------------
1. The navigation scheme for the HTML files should not rely on frames,
and should harmonize with conversion to Microsoft HTML Help (.chm)
format.
2. The output should be structured to make navigable t
gitextract_sf0scbj0/ ├── .babelrc ├── .bumpversion.cfg ├── .clang-format ├── .devcontainer/ │ ├── devcontainer.json │ └── tutorials/ │ └── devcontainer.json ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── ---bug-report.yaml │ │ ├── ---feature-request.yaml │ │ └── config.yml │ ├── dependabot.yml │ └── workflows/ │ ├── build.yml │ ├── build_wheels.yml │ ├── coverage.yml │ ├── docs.yml │ ├── news-check.yml │ ├── sanity-check.yml │ └── test_uv_python.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── MANIFEST.in ├── NEWS.rst ├── README.md ├── asv.conf.json ├── benchmarks/ │ ├── __init__.py │ ├── benchmarking/ │ │ ├── __main__.py │ │ ├── cases/ │ │ │ ├── __init__.py │ │ │ ├── async_tree_base.py │ │ │ ├── async_tree_memray.py │ │ │ ├── deltablue_base.py │ │ │ ├── deltablue_memray.py │ │ │ ├── docutils_data/ │ │ │ │ └── docs/ │ │ │ │ ├── api/ │ │ │ │ │ ├── publisher.txt │ │ │ │ │ ├── runtime-settings.txt │ │ │ │ │ └── transforms.txt │ │ │ │ ├── dev/ │ │ │ │ │ ├── distributing.txt │ │ │ │ │ ├── enthought-plan.txt │ │ │ │ │ ├── enthought-rfp.txt │ │ │ │ │ ├── hacking.txt │ │ │ │ │ ├── policies.txt │ │ │ │ │ ├── pysource.txt │ │ │ │ │ ├── release.txt │ │ │ │ │ ├── repository.txt │ │ │ │ │ ├── rst/ │ │ │ │ │ │ ├── alternatives.txt │ │ │ │ │ │ └── problems.txt │ │ │ │ │ ├── runtime-settings-processing.txt │ │ │ │ │ ├── semantics.txt │ │ │ │ │ ├── testing.txt │ │ │ │ │ ├── todo.txt │ │ │ │ │ └── website.txt │ │ │ │ └── index.txt │ │ │ ├── docutils_html_base.py │ │ │ ├── docutils_html_memray.py │ │ │ ├── fannkuch_base.py │ │ │ ├── fannkuch_memray.py │ │ │ ├── go_base.py │ │ │ ├── go_memray.py │ │ │ ├── hexion_base.py │ │ │ ├── hexion_memray.py │ │ │ ├── json_dumps_base.py │ │ │ ├── json_dumps_memray.py │ │ │ ├── json_loads_base.py │ │ │ ├── json_loads_memray.py │ │ │ ├── mdp_base.py │ │ │ ├── mdp_memray.py │ │ │ ├── meteor_context_base.py │ │ │ ├── meteor_context_memray.py │ │ │ ├── nbody_base.py │ │ │ ├── nbody_memray.py │ │ │ ├── nqueens_base.py │ │ │ ├── nqueens_memray.py │ │ │ ├── pickles_base.py │ │ │ ├── pickles_memray.py │ │ │ ├── pprint_format_base.py │ │ │ ├── pprint_format_memray.py │ │ │ ├── raytrace_base.py │ │ │ ├── raytrace_memray.py │ │ │ ├── regex_dna_base.py │ │ │ ├── regex_dna_memray.py │ │ │ ├── regex_effbot_base.py │ │ │ ├── regex_effbot_memray.py │ │ │ ├── regex_v8_base.py │ │ │ ├── regex_v8_memray.py │ │ │ ├── spectral_norm_base.py │ │ │ ├── spectral_norm_memray.py │ │ │ ├── sqlite_synth_base.py │ │ │ ├── sqlite_synth_memray.py │ │ │ ├── telco_base.py │ │ │ ├── telco_data/ │ │ │ │ └── telco-bench.b │ │ │ └── telco_memray.py │ │ └── plot.py │ ├── benchmarks.py │ └── requirements.txt ├── docs/ │ ├── _static/ │ │ ├── css/ │ │ │ └── custom.css │ │ ├── flamegraphs/ │ │ │ └── .gitattributes │ │ └── js/ │ │ └── custom.js │ ├── _templates/ │ │ └── index.html │ ├── api.rst │ ├── attach.rst │ ├── conf.py │ ├── examples/ │ │ ├── README.rst │ │ ├── fibonacci/ │ │ │ └── fib.py │ │ ├── mandelbrot/ │ │ │ ├── mandelbrot-threaded.py │ │ │ ├── mandelbrot.py │ │ │ └── requirements.txt │ │ ├── nbody/ │ │ │ ├── example.py │ │ │ └── requirements.txt │ │ └── sqlite/ │ │ └── example.py │ ├── flamegraph.rst │ ├── getting_started.rst │ ├── index.rst │ ├── jupyter_magic.rst │ ├── licenses.rst │ ├── live.rst │ ├── manpage.rst │ ├── memory.rst │ ├── native_mode.rst │ ├── overview.rst │ ├── performance.rst │ ├── python_allocators.rst │ ├── run.rst │ ├── stats.rst │ ├── summary.rst │ ├── supported_environments.rst │ ├── table.rst │ ├── temporary_allocations.rst │ ├── transform.rst │ ├── tree.rst │ └── tutorials/ │ ├── 1.rst │ ├── 2.rst │ ├── 3.rst │ ├── Dockerfile │ ├── additional_features.rst │ ├── exercise_1/ │ │ ├── __init__.py │ │ └── fibonacci.py │ ├── exercise_2/ │ │ ├── __init__.py │ │ └── holding_onto_memory.py │ ├── exercise_3/ │ │ ├── __init__.py │ │ └── lru_cache.py │ ├── index.rst │ ├── requirements-tutorial.txt │ ├── solutions/ │ │ ├── exercise_1/ │ │ │ └── fibonacci.py │ │ ├── exercise_2/ │ │ │ └── holding_onto_memory.py │ │ └── exercise_3/ │ │ └── lru_cache.py │ └── tests/ │ ├── __init__.py │ ├── test_exercise_1.py │ ├── test_exercise_2.py │ └── test_exercise_3.py ├── news/ │ └── .gitignore ├── package.json ├── pyproject.toml ├── requirements-docs.txt ├── requirements-extra.txt ├── requirements-test.txt ├── setup.py ├── src/ │ ├── memray/ │ │ ├── __init__.py │ │ ├── __init__.pyi │ │ ├── __main__.py │ │ ├── _destination.py │ │ ├── _errors.py │ │ ├── _ipython/ │ │ │ ├── __init__.py │ │ │ └── flamegraph.py │ │ ├── _memray/ │ │ │ ├── CMakeLists.txt │ │ │ ├── __init__.pxd │ │ │ ├── algorithm.pxd │ │ │ ├── alloc.h │ │ │ ├── alloc.pxd │ │ │ ├── compat.cpp │ │ │ ├── compat.h │ │ │ ├── elf_shenanigans.cpp │ │ │ ├── elf_utils.h │ │ │ ├── exceptions.h │ │ │ ├── frame_tree.h │ │ │ ├── hooks.cpp │ │ │ ├── hooks.h │ │ │ ├── hooks.pxd │ │ │ ├── inject.cpp │ │ │ ├── linker_shenanigans.h │ │ │ ├── logging.cpp │ │ │ ├── logging.h │ │ │ ├── logging.pxd │ │ │ ├── lz4_stream.h │ │ │ ├── macho_shenanigans.cpp │ │ │ ├── macho_utils.h │ │ │ ├── native_resolver.cpp │ │ │ ├── native_resolver.h │ │ │ ├── native_resolver.pxd │ │ │ ├── pthread.pxd │ │ │ ├── python_helpers.cpp │ │ │ ├── python_helpers.h │ │ │ ├── record_reader.cpp │ │ │ ├── record_reader.h │ │ │ ├── record_reader.pxd │ │ │ ├── record_writer.cpp │ │ │ ├── record_writer.h │ │ │ ├── record_writer.pxd │ │ │ ├── records.cpp │ │ │ ├── records.h │ │ │ ├── records.pxd │ │ │ ├── sink.cpp │ │ │ ├── sink.h │ │ │ ├── sink.pxd │ │ │ ├── snapshot.cpp │ │ │ ├── snapshot.h │ │ │ ├── snapshot.pxd │ │ │ ├── socket_reader_thread.cpp │ │ │ ├── socket_reader_thread.h │ │ │ ├── socket_reader_thread.pxd │ │ │ ├── source.cpp │ │ │ ├── source.h │ │ │ ├── source.pxd │ │ │ ├── tracking_api.cpp │ │ │ ├── tracking_api.h │ │ │ └── tracking_api.pxd │ │ ├── _memray.pyi │ │ ├── _memray.pyx │ │ ├── _memray_test_utils.pyx │ │ ├── _metadata.py │ │ ├── _stats.py │ │ ├── _stats.pyi │ │ ├── _test.py │ │ ├── _test_utils.pyi │ │ ├── _thread_name_interceptor.py │ │ ├── _version.py │ │ ├── commands/ │ │ │ ├── __init__.py │ │ │ ├── _attach.gdb │ │ │ ├── _attach.lldb │ │ │ ├── attach.py │ │ │ ├── common.py │ │ │ ├── flamegraph.py │ │ │ ├── live.py │ │ │ ├── parse.py │ │ │ ├── run.py │ │ │ ├── stats.py │ │ │ ├── summary.py │ │ │ ├── table.py │ │ │ ├── transform.py │ │ │ └── tree.py │ │ ├── py.typed │ │ └── reporters/ │ │ ├── __init__.py │ │ ├── _textual_hacks.py │ │ ├── assets/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── common.js │ │ │ ├── common.test.js │ │ │ ├── flamegraph.js │ │ │ ├── flamegraph_common.js │ │ │ ├── table.js │ │ │ └── temporal_flamegraph.js │ │ ├── common.py │ │ ├── flamegraph.py │ │ ├── frame_tools.py │ │ ├── stats.py │ │ ├── summary.py │ │ ├── table.py │ │ ├── templates/ │ │ │ ├── __init__.py │ │ │ ├── assets/ │ │ │ │ ├── .gitattributes │ │ │ │ ├── flamegraph.css │ │ │ │ ├── flamegraph.js │ │ │ │ ├── flamegraph_common.js │ │ │ │ ├── table.css │ │ │ │ ├── table.js │ │ │ │ └── temporal_flamegraph.js │ │ │ ├── base.html │ │ │ ├── classic_base.html │ │ │ ├── flamegraph.html │ │ │ ├── table.html │ │ │ └── temporal_flamegraph.html │ │ ├── transform.py │ │ ├── tree.css │ │ ├── tree.py │ │ ├── tui.css │ │ └── tui.py │ └── vendor/ │ ├── libbacktrace/ │ │ ├── .gitignore │ │ ├── Isaac.Newton-Opticks.txt │ │ ├── LICENSE │ │ ├── Makefile.am │ │ ├── Makefile.in │ │ ├── README.md │ │ ├── aclocal.m4 │ │ ├── alloc.c │ │ ├── allocfail.c │ │ ├── allocfail.sh │ │ ├── atomic.c │ │ ├── backtrace-supported.h.in │ │ ├── backtrace.c │ │ ├── backtrace.h │ │ ├── btest.c │ │ ├── compile │ │ ├── config/ │ │ │ ├── enable.m4 │ │ │ ├── lead-dot.m4 │ │ │ ├── libtool.m4 │ │ │ ├── ltoptions.m4 │ │ │ ├── ltsugar.m4 │ │ │ ├── ltversion.m4 │ │ │ ├── lt~obsolete.m4 │ │ │ ├── multi.m4 │ │ │ ├── override.m4 │ │ │ ├── unwind_ipinfo.m4 │ │ │ └── warnings.m4 │ │ ├── config.guess │ │ ├── config.h.in │ │ ├── config.sub │ │ ├── configure │ │ ├── configure.ac │ │ ├── debuginfod_support.h │ │ ├── dwarf.c │ │ ├── edtest.c │ │ ├── edtest2.c │ │ ├── elf.c │ │ ├── fileline.c │ │ ├── filenames.h │ │ ├── filetype.awk │ │ ├── install-debuginfo-for-buildid.sh.in │ │ ├── install-sh │ │ ├── instrumented_alloc.c │ │ ├── internal.h │ │ ├── ltmain.sh │ │ ├── macho.c │ │ ├── missing │ │ ├── mmap.c │ │ ├── mmapio.c │ │ ├── move-if-change │ │ ├── mtest.c │ │ ├── nounwind.c │ │ ├── pecoff.c │ │ ├── posix.c │ │ ├── print.c │ │ ├── read.c │ │ ├── simple.c │ │ ├── sort.c │ │ ├── state.c │ │ ├── stest.c │ │ ├── test-driver │ │ ├── test_format.c │ │ ├── testlib.c │ │ ├── testlib.h │ │ ├── ttest.c │ │ ├── unittest.c │ │ ├── unknown.c │ │ ├── xcoff.c │ │ ├── xztest.c │ │ ├── zstdtest.c │ │ └── ztest.c │ ├── libbacktrace-patches/ │ │ ├── 0001-Expose-some-internal-functions-of-libbacktrace.patch │ │ └── 0002-Add-debuginfod-support-to-libbacktrace.patch │ └── regenerate_libbacktrace.sh ├── tests/ │ ├── __init__.py │ ├── conftest.py │ ├── integration/ │ │ ├── __init__.py │ │ ├── misbehaving_extension/ │ │ │ ├── __init__.py │ │ │ ├── misbehaving.cpp │ │ │ └── setup.py │ │ ├── multithreaded_extension/ │ │ │ ├── __init__.py │ │ │ ├── main.py │ │ │ ├── setup.py │ │ │ └── testext.cpp │ │ ├── native_extension/ │ │ │ ├── main.py │ │ │ ├── native_ext.c │ │ │ └── setup.py │ │ ├── rpath_extension/ │ │ │ ├── ext.c │ │ │ ├── setup.py │ │ │ └── sharedlibs/ │ │ │ └── sharedlib.c │ │ ├── test_api.py │ │ ├── test_attach.py │ │ ├── test_extensions.py │ │ ├── test_greenlet.py │ │ ├── test_ipython.py │ │ ├── test_main.py │ │ ├── test_native_tracking.py │ │ ├── test_object_tracking.py │ │ ├── test_processes.py │ │ ├── test_record_writer.py │ │ ├── test_socket.py │ │ ├── test_threads.py │ │ ├── test_tracing.py │ │ └── test_tracking.py │ ├── test_utils.py │ ├── unit/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_allocation_lifetime_aggregator.py │ │ ├── test_attach.py │ │ ├── test_cli.py │ │ ├── test_flamegraph_reporter.py │ │ ├── test_frame_tools.py │ │ ├── test_high_water_mark_aggregator.py │ │ ├── test_highwatermark_command.py │ │ ├── test_reader.py │ │ ├── test_stats_reporter.py │ │ ├── test_summary_reporter.py │ │ ├── test_table_reporter.py │ │ ├── test_templates.py │ │ ├── test_tracker.py │ │ ├── test_transform_reporter.py │ │ ├── test_tree_reporter.py │ │ └── test_tui_reporter.py │ └── utils.py ├── valgrind.supp └── webpack.config.js
Showing preview only (214K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2731 symbols across 218 files)
FILE: benchmarks/benchmarking/__main__.py
class Case (line 18) | class Case:
method run_case (line 23) | def run_case(
method run (line 49) | def run(self) -> None:
class BenchmarkResult (line 161) | class BenchmarkResult:
function gather_benchmarks (line 166) | def gather_benchmarks(cases):
FILE: benchmarks/benchmarking/cases/async_tree_base.py
class AsyncTree (line 30) | class AsyncTree:
method __init__ (line 31) | def __init__(self):
method mock_io_call (line 36) | async def mock_io_call(self):
method workload_func (line 39) | async def workload_func(self):
method recurse (line 42) | async def recurse(self, recurse_level):
method run (line 51) | async def run(self):
class NoneAsyncTree (line 55) | class NoneAsyncTree(AsyncTree):
method workload_func (line 56) | async def workload_func(self):
class IOAsyncTree (line 60) | class IOAsyncTree(AsyncTree):
method workload_func (line 61) | async def workload_func(self):
class MemoizationAsyncTree (line 65) | class MemoizationAsyncTree(AsyncTree):
method workload_func (line 66) | async def workload_func(self):
class CpuIoMixedAsyncTree (line 80) | class CpuIoMixedAsyncTree(MemoizationAsyncTree):
method workload_func (line 81) | async def workload_func(self):
function add_metadata (line 90) | def add_metadata(runner):
function add_cmdline_args (line 101) | def add_cmdline_args(cmd, args):
function add_parser_args (line 105) | def add_parser_args(parser):
function run_benchmark (line 130) | def run_benchmark(benchmark):
FILE: benchmarks/benchmarking/cases/async_tree_memray.py
class AsyncTree (line 34) | class AsyncTree:
method __init__ (line 35) | def __init__(self):
method mock_io_call (line 40) | async def mock_io_call(self):
method workload_func (line 43) | async def workload_func(self):
method recurse (line 46) | async def recurse(self, recurse_level):
method run (line 55) | async def run(self):
class NoneAsyncTree (line 60) | class NoneAsyncTree(AsyncTree):
method workload_func (line 61) | async def workload_func(self):
class IOAsyncTree (line 65) | class IOAsyncTree(AsyncTree):
method workload_func (line 66) | async def workload_func(self):
class MemoizationAsyncTree (line 70) | class MemoizationAsyncTree(AsyncTree):
method workload_func (line 71) | async def workload_func(self):
class CpuIoMixedAsyncTree (line 85) | class CpuIoMixedAsyncTree(MemoizationAsyncTree):
method workload_func (line 86) | async def workload_func(self):
function add_metadata (line 95) | def add_metadata(runner):
function add_cmdline_args (line 106) | def add_cmdline_args(cmd, args):
function add_parser_args (line 110) | def add_parser_args(parser):
FILE: benchmarks/benchmarking/cases/deltablue_base.py
class OrderedCollection (line 23) | class OrderedCollection(list):
class Strength (line 27) | class Strength(object):
method __init__ (line 36) | def __init__(self, strength, name):
method stronger (line 42) | def stronger(cls, s1, s2):
method weaker (line 46) | def weaker(cls, s1, s2):
method weakest_of (line 50) | def weakest_of(cls, s1, s2):
method strongest (line 57) | def strongest(cls, s1, s2):
method next_weaker (line 63) | def next_weaker(self):
class Constraint (line 87) | class Constraint(object):
method __init__ (line 88) | def __init__(self, strength):
method add_constraint (line 92) | def add_constraint(self):
method satisfy (line 97) | def satisfy(self, mark):
method destroy_constraint (line 122) | def destroy_constraint(self):
method is_input (line 129) | def is_input(self):
class UrnaryConstraint (line 133) | class UrnaryConstraint(Constraint):
method __init__ (line 134) | def __init__(self, v, strength):
method add_to_graph (line 140) | def add_to_graph(self):
method choose_method (line 144) | def choose_method(self, mark):
method is_satisfied (line 152) | def is_satisfied(self):
method mark_inputs (line 155) | def mark_inputs(self, mark):
method output (line 159) | def output(self):
method recalculate (line 164) | def recalculate(self):
method mark_unsatisfied (line 171) | def mark_unsatisfied(self):
method inputs_known (line 174) | def inputs_known(self, mark):
method remove_from_graph (line 177) | def remove_from_graph(self):
class StayConstraint (line 183) | class StayConstraint(UrnaryConstraint):
method __init__ (line 184) | def __init__(self, v, string):
method execute (line 187) | def execute(self):
class EditConstraint (line 192) | class EditConstraint(UrnaryConstraint):
method __init__ (line 193) | def __init__(self, v, string):
method is_input (line 196) | def is_input(self):
method execute (line 199) | def execute(self):
class Direction (line 204) | class Direction(object):
class BinaryConstraint (line 211) | class BinaryConstraint(Constraint):
method __init__ (line 212) | def __init__(self, v1, v2, strength):
method choose_method (line 219) | def choose_method(self, mark):
method add_to_graph (line 247) | def add_to_graph(self):
method is_satisfied (line 252) | def is_satisfied(self):
method mark_inputs (line 255) | def mark_inputs(self, mark):
method input (line 258) | def input(self):
method output (line 264) | def output(self):
method recalculate (line 270) | def recalculate(self):
method mark_unsatisfied (line 279) | def mark_unsatisfied(self):
method inputs_known (line 282) | def inputs_known(self, mark):
method remove_from_graph (line 286) | def remove_from_graph(self):
class ScaleConstraint (line 296) | class ScaleConstraint(BinaryConstraint):
method __init__ (line 297) | def __init__(self, src, scale, offset, dest, strength):
method add_to_graph (line 303) | def add_to_graph(self):
method remove_from_graph (line 308) | def remove_from_graph(self):
method mark_inputs (line 317) | def mark_inputs(self, mark):
method execute (line 322) | def execute(self):
method recalculate (line 328) | def recalculate(self):
class EqualityConstraint (line 338) | class EqualityConstraint(BinaryConstraint):
method execute (line 339) | def execute(self):
class Variable (line 343) | class Variable(object):
method __init__ (line 344) | def __init__(self, name, initial_value=0):
method __repr__ (line 354) | def __repr__(self):
method add_constraint (line 358) | def add_constraint(self, constraint):
method remove_constraint (line 361) | def remove_constraint(self, constraint):
class Planner (line 368) | class Planner(object):
method __init__ (line 369) | def __init__(self):
method incremental_add (line 373) | def incremental_add(self, constraint):
method incremental_remove (line 380) | def incremental_remove(self, constraint):
method new_mark (line 398) | def new_mark(self):
method make_plan (line 402) | def make_plan(self, sources):
method extract_plan_from_constraints (line 417) | def extract_plan_from_constraints(self, constraints):
method add_propagate (line 426) | def add_propagate(self, c, mark):
method remove_propagate_from (line 442) | def remove_propagate_from(self, out):
method add_constraints_consuming_to (line 466) | def add_constraints_consuming_to(self, v, coll):
class Plan (line 478) | class Plan(object):
method __init__ (line 479) | def __init__(self):
method add_constraint (line 483) | def add_constraint(self, c):
method __len__ (line 486) | def __len__(self):
method __getitem__ (line 489) | def __getitem__(self, index):
method execute (line 492) | def execute(self):
function chain_test (line 500) | def chain_test(n):
function projection_test (line 548) | def projection_test(n):
function change (line 593) | def change(v, new_value):
function delta_blue (line 613) | def delta_blue(n):
function run_benchmark (line 618) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/deltablue_memray.py
class OrderedCollection (line 26) | class OrderedCollection(list):
class Strength (line 30) | class Strength(object):
method __init__ (line 39) | def __init__(self, strength, name):
method stronger (line 45) | def stronger(cls, s1, s2):
method weaker (line 49) | def weaker(cls, s1, s2):
method weakest_of (line 53) | def weakest_of(cls, s1, s2):
method strongest (line 60) | def strongest(cls, s1, s2):
method next_weaker (line 66) | def next_weaker(self):
class Constraint (line 90) | class Constraint(object):
method __init__ (line 91) | def __init__(self, strength):
method add_constraint (line 95) | def add_constraint(self):
method satisfy (line 100) | def satisfy(self, mark):
method destroy_constraint (line 125) | def destroy_constraint(self):
method is_input (line 132) | def is_input(self):
class UrnaryConstraint (line 136) | class UrnaryConstraint(Constraint):
method __init__ (line 137) | def __init__(self, v, strength):
method add_to_graph (line 143) | def add_to_graph(self):
method choose_method (line 147) | def choose_method(self, mark):
method is_satisfied (line 155) | def is_satisfied(self):
method mark_inputs (line 158) | def mark_inputs(self, mark):
method output (line 162) | def output(self):
method recalculate (line 167) | def recalculate(self):
method mark_unsatisfied (line 174) | def mark_unsatisfied(self):
method inputs_known (line 177) | def inputs_known(self, mark):
method remove_from_graph (line 180) | def remove_from_graph(self):
class StayConstraint (line 186) | class StayConstraint(UrnaryConstraint):
method __init__ (line 187) | def __init__(self, v, string):
method execute (line 190) | def execute(self):
class EditConstraint (line 195) | class EditConstraint(UrnaryConstraint):
method __init__ (line 196) | def __init__(self, v, string):
method is_input (line 199) | def is_input(self):
method execute (line 202) | def execute(self):
class Direction (line 207) | class Direction(object):
class BinaryConstraint (line 214) | class BinaryConstraint(Constraint):
method __init__ (line 215) | def __init__(self, v1, v2, strength):
method choose_method (line 222) | def choose_method(self, mark):
method add_to_graph (line 250) | def add_to_graph(self):
method is_satisfied (line 255) | def is_satisfied(self):
method mark_inputs (line 258) | def mark_inputs(self, mark):
method input (line 261) | def input(self):
method output (line 267) | def output(self):
method recalculate (line 273) | def recalculate(self):
method mark_unsatisfied (line 282) | def mark_unsatisfied(self):
method inputs_known (line 285) | def inputs_known(self, mark):
method remove_from_graph (line 289) | def remove_from_graph(self):
class ScaleConstraint (line 299) | class ScaleConstraint(BinaryConstraint):
method __init__ (line 300) | def __init__(self, src, scale, offset, dest, strength):
method add_to_graph (line 306) | def add_to_graph(self):
method remove_from_graph (line 311) | def remove_from_graph(self):
method mark_inputs (line 320) | def mark_inputs(self, mark):
method execute (line 325) | def execute(self):
method recalculate (line 331) | def recalculate(self):
class EqualityConstraint (line 341) | class EqualityConstraint(BinaryConstraint):
method execute (line 342) | def execute(self):
class Variable (line 346) | class Variable(object):
method __init__ (line 347) | def __init__(self, name, initial_value=0):
method __repr__ (line 357) | def __repr__(self):
method add_constraint (line 361) | def add_constraint(self, constraint):
method remove_constraint (line 364) | def remove_constraint(self, constraint):
class Planner (line 371) | class Planner(object):
method __init__ (line 372) | def __init__(self):
method incremental_add (line 376) | def incremental_add(self, constraint):
method incremental_remove (line 383) | def incremental_remove(self, constraint):
method new_mark (line 401) | def new_mark(self):
method make_plan (line 405) | def make_plan(self, sources):
method extract_plan_from_constraints (line 420) | def extract_plan_from_constraints(self, constraints):
method add_propagate (line 429) | def add_propagate(self, c, mark):
method remove_propagate_from (line 445) | def remove_propagate_from(self, out):
method add_constraints_consuming_to (line 469) | def add_constraints_consuming_to(self, v, coll):
class Plan (line 481) | class Plan(object):
method __init__ (line 482) | def __init__(self):
method add_constraint (line 486) | def add_constraint(self, c):
method __len__ (line 489) | def __len__(self):
method __getitem__ (line 492) | def __getitem__(self, index):
method execute (line 495) | def execute(self):
function chain_test (line 503) | def chain_test(n):
function projection_test (line 551) | def projection_test(n):
function change (line 596) | def change(v, new_value):
function delta_blue (line 616) | def delta_blue(n):
function bench_deltablue (line 621) | def bench_deltablue(loops, n):
FILE: benchmarks/benchmarking/cases/docutils_html_base.py
function build_html (line 25) | def build_html(doc_root):
function bench_docutils (line 47) | def bench_docutils(loops, doc_root):
function run_benchmark (line 54) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/docutils_html_memray.py
function build_html (line 20) | def build_html(doc_root):
function bench_docutils (line 42) | def bench_docutils(loops, doc_root):
function add_cmdline_args (line 49) | def add_cmdline_args(cmd, args):
FILE: benchmarks/benchmarking/cases/fannkuch_base.py
function fannkuch (line 11) | def fannkuch(n):
function run_benchmark (line 48) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/fannkuch_memray.py
function fannkuch (line 15) | def fannkuch(n):
function _fannkuch (line 20) | def _fannkuch(n):
FILE: benchmarks/benchmarking/cases/go_base.py
function to_pos (line 18) | def to_pos(x, y):
function to_xy (line 22) | def to_xy(pos):
class Square (line 27) | class Square:
method __init__ (line 28) | def __init__(self, board, pos):
method set_neighbours (line 35) | def set_neighbours(self):
method move (line 43) | def move(self, color):
method remove (line 69) | def remove(self, reference, update=True):
method find (line 88) | def find(self, update=False):
method __repr__ (line 96) | def __repr__(self):
class EmptySet (line 100) | class EmptySet:
method __init__ (line 101) | def __init__(self, board):
method random_choice (line 106) | def random_choice(self):
method add (line 118) | def add(self, pos):
method remove (line 122) | def remove(self, pos):
method set (line 126) | def set(self, i, pos):
class ZobristHash (line 131) | class ZobristHash:
method __init__ (line 132) | def __init__(self, board):
method update (line 141) | def update(self, square, color):
method add (line 145) | def add(self):
method dupe (line 148) | def dupe(self):
class Board (line 152) | class Board:
method __init__ (line 153) | def __init__(self):
method reset (line 159) | def reset(self):
method move (line 172) | def move(self, pos):
method random_move (line 186) | def random_move(self):
method useful_fast (line 189) | def useful_fast(self, square):
method useful (line 196) | def useful(self, pos):
method useful_moves (line 233) | def useful_moves(self):
method replay (line 236) | def replay(self, history):
method score (line 240) | def score(self, color):
method check (line 258) | def check(self):
method __repr__ (line 309) | def __repr__(self):
class UCTNode (line 324) | class UCTNode:
method __init__ (line 325) | def __init__(self):
method play (line 333) | def play(self, board):
method select (line 356) | def select(self, board):
method random_playout (line 369) | def random_playout(self, board):
method update_path (line 376) | def update_path(self, board, color, path):
method score (line 391) | def score(self):
method best_child (line 399) | def best_child(self):
method best_visited (line 408) | def best_visited(self):
function computer_move (line 437) | def computer_move(board):
function versus_cpu (line 452) | def versus_cpu():
function run_benchmark (line 458) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/go_memray.py
function to_pos (line 22) | def to_pos(x, y):
function to_xy (line 26) | def to_xy(pos):
class Square (line 31) | class Square:
method __init__ (line 32) | def __init__(self, board, pos):
method set_neighbours (line 39) | def set_neighbours(self):
method move (line 47) | def move(self, color):
method remove (line 73) | def remove(self, reference, update=True):
method find (line 92) | def find(self, update=False):
method __repr__ (line 100) | def __repr__(self):
class EmptySet (line 104) | class EmptySet:
method __init__ (line 105) | def __init__(self, board):
method random_choice (line 110) | def random_choice(self):
method add (line 122) | def add(self, pos):
method remove (line 126) | def remove(self, pos):
method set (line 130) | def set(self, i, pos):
class ZobristHash (line 135) | class ZobristHash:
method __init__ (line 136) | def __init__(self, board):
method update (line 145) | def update(self, square, color):
method add (line 149) | def add(self):
method dupe (line 152) | def dupe(self):
class Board (line 156) | class Board:
method __init__ (line 157) | def __init__(self):
method reset (line 163) | def reset(self):
method move (line 176) | def move(self, pos):
method random_move (line 190) | def random_move(self):
method useful_fast (line 193) | def useful_fast(self, square):
method useful (line 200) | def useful(self, pos):
method useful_moves (line 237) | def useful_moves(self):
method replay (line 240) | def replay(self, history):
method score (line 244) | def score(self, color):
method check (line 262) | def check(self):
method __repr__ (line 313) | def __repr__(self):
class UCTNode (line 328) | class UCTNode:
method __init__ (line 329) | def __init__(self):
method play (line 337) | def play(self, board):
method select (line 360) | def select(self, board):
method random_playout (line 373) | def random_playout(self, board):
method update_path (line 380) | def update_path(self, board, color, path):
method score (line 395) | def score(self):
method best_child (line 403) | def best_child(self):
method best_visited (line 412) | def best_visited(self):
function computer_move (line 441) | def computer_move(board):
function versus_cpu (line 456) | def versus_cpu():
FILE: benchmarks/benchmarking/cases/hexion_base.py
class Dir (line 18) | class Dir(object):
method __init__ (line 19) | def __init__(self, x, y):
class Done (line 31) | class Done(object):
method __init__ (line 39) | def __init__(self, count, empty=False):
method clone (line 45) | def clone(self):
method __getitem__ (line 50) | def __getitem__(self, i):
method set_done (line 53) | def set_done(self, i, v):
method already_done (line 56) | def already_done(self, i):
method remove (line 59) | def remove(self, i, v):
method remove_all (line 66) | def remove_all(self, v):
method remove_unfixed (line 70) | def remove_unfixed(self, v):
method filter_tiles (line 78) | def filter_tiles(self, tiles):
method next_cell_min_choice (line 83) | def next_cell_min_choice(self):
method next_cell_max_choice (line 92) | def next_cell_max_choice(self):
method next_cell_highest_value (line 101) | def next_cell_highest_value(self):
method next_cell_first (line 112) | def next_cell_first(self):
method next_cell_max_neighbors (line 118) | def next_cell_max_neighbors(self, pos):
method next_cell_min_neighbors (line 133) | def next_cell_min_neighbors(self, pos):
method next_cell (line 148) | def next_cell(self, pos, strategy=HIGHEST_VALUE_STRATEGY):
class Node (line 168) | class Node(object):
method __init__ (line 169) | def __init__(self, pos, id, links):
class Hex (line 178) | class Hex(object):
method __init__ (line 179) | def __init__(self, size):
method link_nodes (line 201) | def link_nodes(self):
method contains_pos (line 210) | def contains_pos(self, pos):
method get_by_pos (line 213) | def get_by_pos(self, pos):
method get_by_id (line 216) | def get_by_id(self, id):
class Pos (line 221) | class Pos(object):
method __init__ (line 222) | def __init__(self, hex, tiles, done=None):
method clone (line 227) | def clone(self):
function constraint_pass (line 234) | def constraint_pass(pos, last_move=None):
function find_moves (line 319) | def find_moves(pos, strategy, order):
function play_move (line 335) | def play_move(pos, move):
function print_pos (line 340) | def print_pos(pos, output):
function solved (line 374) | def solved(pos, output, verbose=False):
function solve_step (line 414) | def solve_step(prev, strategy, order, output, first=False):
function check_valid (line 444) | def check_valid(pos):
function solve (line 459) | def solve(pos, strategy, order, output):
function read_file (line 467) | def read_file(file):
function solve_file (line 515) | def solve_file(file, strategy, order, output):
function main (line 635) | def main(loops, level):
function run_benchmark (line 659) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/hexion_memray.py
class Dir (line 21) | class Dir(object):
method __init__ (line 22) | def __init__(self, x, y):
class Done (line 34) | class Done(object):
method __init__ (line 42) | def __init__(self, count, empty=False):
method clone (line 48) | def clone(self):
method __getitem__ (line 53) | def __getitem__(self, i):
method set_done (line 56) | def set_done(self, i, v):
method already_done (line 59) | def already_done(self, i):
method remove (line 62) | def remove(self, i, v):
method remove_all (line 69) | def remove_all(self, v):
method remove_unfixed (line 73) | def remove_unfixed(self, v):
method filter_tiles (line 81) | def filter_tiles(self, tiles):
method next_cell_min_choice (line 86) | def next_cell_min_choice(self):
method next_cell_max_choice (line 95) | def next_cell_max_choice(self):
method next_cell_highest_value (line 104) | def next_cell_highest_value(self):
method next_cell_first (line 115) | def next_cell_first(self):
method next_cell_max_neighbors (line 121) | def next_cell_max_neighbors(self, pos):
method next_cell_min_neighbors (line 136) | def next_cell_min_neighbors(self, pos):
method next_cell (line 151) | def next_cell(self, pos, strategy=HIGHEST_VALUE_STRATEGY):
class Node (line 171) | class Node(object):
method __init__ (line 172) | def __init__(self, pos, id, links):
class Hex (line 181) | class Hex(object):
method __init__ (line 182) | def __init__(self, size):
method link_nodes (line 204) | def link_nodes(self):
method contains_pos (line 213) | def contains_pos(self, pos):
method get_by_pos (line 216) | def get_by_pos(self, pos):
method get_by_id (line 219) | def get_by_id(self, id):
class Pos (line 224) | class Pos(object):
method __init__ (line 225) | def __init__(self, hex, tiles, done=None):
method clone (line 230) | def clone(self):
function constraint_pass (line 237) | def constraint_pass(pos, last_move=None):
function find_moves (line 322) | def find_moves(pos, strategy, order):
function play_move (line 338) | def play_move(pos, move):
function print_pos (line 343) | def print_pos(pos, output):
function solved (line 377) | def solved(pos, output, verbose=False):
function solve_step (line 417) | def solve_step(prev, strategy, order, output, first=False):
function check_valid (line 447) | def check_valid(pos):
function solve (line 462) | def solve(pos, strategy, order, output):
function read_file (line 470) | def read_file(file):
function solve_file (line 518) | def solve_file(file, strategy, order, output):
function main (line 638) | def main(loops, level):
function add_cmdline_args (line 667) | def add_cmdline_args(cmd, args):
FILE: benchmarks/benchmarking/cases/json_dumps_base.py
function bench_json_dumps (line 28) | def bench_json_dumps(data):
function add_cmdline_args (line 34) | def add_cmdline_args(cmd, args):
function run_benchmark (line 39) | def run_benchmark():
function main (line 47) | def main():
FILE: benchmarks/benchmarking/cases/json_dumps_memray.py
function bench_json_dumps (line 31) | def bench_json_dumps(data):
function add_cmdline_args (line 38) | def add_cmdline_args(cmd, args):
function main (line 43) | def main():
FILE: benchmarks/benchmarking/cases/json_loads_base.py
function mutate_dict (line 78) | def mutate_dict(orig_dict, random_source):
function bench_json_loads (line 91) | def bench_json_loads(objs):
function run_benchmark (line 116) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/json_loads_memray.py
function mutate_dict (line 80) | def mutate_dict(orig_dict, random_source):
function bench_json_loads (line 93) | def bench_json_loads(loops, objs):
FILE: benchmarks/benchmarking/cases/mdp_base.py
function topoSort (line 6) | def topoSort(roots, getParents):
function getDamages (line 33) | def getDamages(L, A, D, B, stab, te):
function getCritDist (line 42) | def getCritDist(L, p, A1, A2, D1, D2, B, stab, te):
function plus12 (line 55) | def plus12(x):
function applyHPChange (line 71) | def applyHPChange(hstate, change):
function applyBadgeBoosts (line 76) | def applyBadgeBoosts(badges, stats):
function _applyActionSide1 (line 92) | def _applyActionSide1(state, act):
function _applyAction (line 122) | def _applyAction(state, side, act):
class Battle (line 131) | class Battle(object):
method __init__ (line 132) | def __init__(self):
method _getSuccessorsA (line 144) | def _getSuccessorsA(self, statep):
method _applyActionPair (line 149) | def _applyActionPair(self, state, side1, act1, side2, act2, dist, pmult):
method _getSuccessorsB (line 159) | def _getSuccessorsB(self, statep):
method _getSuccessorsC (line 179) | def _getSuccessorsC(self, statep):
method getSuccessors (line 192) | def getSuccessors(self, statep):
method getSuccessorsList (line 208) | def getSuccessorsList(self, statep):
method evaluate (line 216) | def evaluate(self, tolerance=0.15):
function bench_mdp (line 253) | def bench_mdp(loops):
function run_benchmark (line 268) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/mdp_memray.py
function topoSort (line 9) | def topoSort(roots, getParents):
function getDamages (line 36) | def getDamages(L, A, D, B, stab, te):
function getCritDist (line 45) | def getCritDist(L, p, A1, A2, D1, D2, B, stab, te):
function plus12 (line 58) | def plus12(x):
function applyHPChange (line 74) | def applyHPChange(hstate, change):
function applyBadgeBoosts (line 79) | def applyBadgeBoosts(badges, stats):
function _applyActionSide1 (line 95) | def _applyActionSide1(state, act):
function _applyAction (line 125) | def _applyAction(state, side, act):
class Battle (line 134) | class Battle(object):
method __init__ (line 135) | def __init__(self):
method _getSuccessorsA (line 147) | def _getSuccessorsA(self, statep):
method _applyActionPair (line 152) | def _applyActionPair(self, state, side1, act1, side2, act2, dist, pmult):
method _getSuccessorsB (line 162) | def _getSuccessorsB(self, statep):
method _getSuccessorsC (line 182) | def _getSuccessorsC(self, statep):
method getSuccessors (line 195) | def getSuccessors(self, statep):
method getSuccessorsList (line 211) | def getSuccessorsList(self, statep):
method evaluate (line 219) | def evaluate(self, tolerance=0.15):
function bench_mdp (line 256) | def bench_mdp(loops):
FILE: benchmarks/benchmarking/cases/meteor_context_base.py
function rotate (line 86) | def rotate(ido, rd={E: NE, NE: NW, NW: W, W: SW, SW: SE, SE: E}):
function flip (line 90) | def flip(ido, fd={E: E, NE: SE, NW: SW, W: W, SW: NW, SE: NE}):
function permute (line 94) | def permute(ido, r_ido, rotate=rotate, flip=flip):
function convert (line 105) | def convert(ido):
function get_footprints (line 113) | def get_footprints(board, cti, pieces):
function get_senh (line 124) | def get_senh(board, cti):
function get_puzzle (line 133) | def get_puzzle(width, height):
function solve (line 157) | def solve(
function bench_meteor_contest (line 207) | def bench_meteor_contest(loops, board, pieces, solve_arg, fps, se_nh):
function run_benchmark (line 220) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/meteor_context_memray.py
function rotate (line 90) | def rotate(ido, rd={E: NE, NE: NW, NW: W, W: SW, SW: SE, SE: E}):
function flip (line 94) | def flip(ido, fd={E: E, NE: SE, NW: SW, W: W, SW: NW, SE: NE}):
function permute (line 98) | def permute(ido, r_ido, rotate=rotate, flip=flip):
function convert (line 109) | def convert(ido):
function get_footprints (line 117) | def get_footprints(board, cti, pieces):
function get_senh (line 128) | def get_senh(board, cti):
function get_puzzle (line 137) | def get_puzzle(width, height):
function solve (line 161) | def solve(
function bench_meteor_contest (line 211) | def bench_meteor_contest(loops, board, pieces, solve_arg, fps, se_nh):
function main (line 231) | def main():
FILE: benchmarks/benchmarking/cases/nbody_base.py
function combinations (line 22) | def combinations(l):
function advance (line 81) | def advance(dt, n, bodies=SYSTEM, pairs=PAIRS):
function report_energy (line 102) | def report_energy(bodies=SYSTEM, pairs=PAIRS, e=0.0):
function offset_momentum (line 113) | def offset_momentum(ref, bodies=SYSTEM, px=0.0, py=0.0, pz=0.0):
function bench_nbody (line 124) | def bench_nbody(loops, reference, iterations):
function add_cmdline_args (line 136) | def add_cmdline_args(cmd, args):
function run_benchmark (line 140) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/nbody_memray.py
function combinations (line 25) | def combinations(l):
function advance (line 84) | def advance(dt, n, bodies=SYSTEM, pairs=PAIRS):
function report_energy (line 105) | def report_energy(bodies=SYSTEM, pairs=PAIRS, e=0.0):
function offset_momentum (line 116) | def offset_momentum(ref, bodies=SYSTEM, px=0.0, py=0.0, pz=0.0):
function bench_nbody (line 127) | def bench_nbody(loops, reference, iterations):
function add_cmdline_args (line 143) | def add_cmdline_args(cmd, args):
FILE: benchmarks/benchmarking/cases/nqueens_base.py
function permutations (line 7) | def permutations(iterable, r=None):
function n_queens (line 32) | def n_queens(queen_count):
function bench_n_queens (line 54) | def bench_n_queens(queen_count):
function run_benchmark (line 58) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/nqueens_memray.py
function permutations (line 10) | def permutations(iterable, r=None):
function n_queens (line 35) | def n_queens(queen_count):
function bench_n_queens (line 57) | def bench_n_queens(queen_count):
FILE: benchmarks/benchmarking/cases/pickles_base.py
function mutate_dict (line 86) | def mutate_dict(orig_dict, random_source):
function bench_pickle (line 99) | def bench_pickle(loops, pickle, protocol):
function bench_unpickle (line 130) | def bench_unpickle(loops, pickle, protocol):
function bench_pickle_list (line 168) | def bench_pickle_list(loops, pickle, protocol):
function bench_unpickle_list (line 189) | def bench_unpickle_list(loops, pickle, protocol):
function bench_pickle_dict (line 213) | def bench_pickle_dict(loops, pickle, protocol):
function is_accelerated_module (line 239) | def is_accelerated_module(module):
function add_cmdline_args (line 243) | def add_cmdline_args(cmd, args):
function run_benchmark_pure_python (line 250) | def run_benchmark_pure_python(benchmark):
function run_benchmark_c (line 261) | def run_benchmark_c(benchmark):
FILE: benchmarks/benchmarking/cases/pickles_memray.py
function mutate_dict (line 89) | def mutate_dict(orig_dict, random_source):
function bench_pickle (line 102) | def bench_pickle(loops, pickle, options):
function bench_unpickle (line 139) | def bench_unpickle(loops, pickle, options):
function bench_pickle_list (line 181) | def bench_pickle_list(loops, pickle, options):
function bench_unpickle_list (line 206) | def bench_unpickle_list(loops, pickle, options):
function bench_pickle_dict (line 234) | def bench_pickle_dict(loops, pickle, options):
function is_accelerated_module (line 264) | def is_accelerated_module(module):
function add_cmdline_args (line 268) | def add_cmdline_args(cmd, args):
FILE: benchmarks/benchmarking/cases/pprint_format_base.py
function run_benchmark (line 14) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/pprint_format_memray.py
function format (line 17) | def format(*args, **kwrags):
function safe_repr (line 22) | def safe_repr(*args, **kwargs):
FILE: benchmarks/benchmarking/cases/raytrace_base.py
class Vector (line 20) | class Vector(object):
method __init__ (line 21) | def __init__(self, initx, inity, initz):
method __str__ (line 26) | def __str__(self):
method __repr__ (line 29) | def __repr__(self):
method magnitude (line 32) | def magnitude(self):
method __add__ (line 35) | def __add__(self, other):
method __sub__ (line 41) | def __sub__(self, other):
method scale (line 45) | def scale(self, factor):
method dot (line 48) | def dot(self, other):
method cross (line 52) | def cross(self, other):
method normalized (line 60) | def normalized(self):
method negated (line 63) | def negated(self):
method __eq__ (line 66) | def __eq__(self, other):
method isVector (line 69) | def isVector(self):
method isPoint (line 72) | def isPoint(self):
method mustBeVector (line 75) | def mustBeVector(self):
method mustBePoint (line 78) | def mustBePoint(self):
method reflectThrough (line 81) | def reflectThrough(self, normal):
class Point (line 95) | class Point(object):
method __init__ (line 96) | def __init__(self, initx, inity, initz):
method __str__ (line 101) | def __str__(self):
method __repr__ (line 104) | def __repr__(self):
method __add__ (line 107) | def __add__(self, other):
method __sub__ (line 111) | def __sub__(self, other):
method isVector (line 117) | def isVector(self):
method isPoint (line 120) | def isPoint(self):
method mustBeVector (line 123) | def mustBeVector(self):
method mustBePoint (line 126) | def mustBePoint(self):
class Sphere (line 130) | class Sphere(object):
method __init__ (line 131) | def __init__(self, centre, radius):
method __repr__ (line 136) | def __repr__(self):
method intersectionTime (line 139) | def intersectionTime(self, ray):
method normalAt (line 148) | def normalAt(self, p):
class Halfspace (line 152) | class Halfspace(object):
method __init__ (line 153) | def __init__(self, point, normal):
method __repr__ (line 157) | def __repr__(self):
method intersectionTime (line 160) | def intersectionTime(self, ray):
method normalAt (line 167) | def normalAt(self, p):
class Ray (line 171) | class Ray(object):
method __init__ (line 172) | def __init__(self, point, vector):
method __repr__ (line 176) | def __repr__(self):
method pointAtTime (line 179) | def pointAtTime(self, t):
class Canvas (line 186) | class Canvas(object):
method __init__ (line 187) | def __init__(self, width, height):
method plot (line 194) | def plot(self, x, y, r, g, b):
method write_ppm (line 200) | def write_ppm(self, filename):
function firstIntersection (line 207) | def firstIntersection(intersections):
class Scene (line 217) | class Scene(object):
method __init__ (line 218) | def __init__(self):
method moveTo (line 226) | def moveTo(self, p):
method lookAt (line 229) | def lookAt(self, p):
method addObject (line 232) | def addObject(self, object, surface):
method addLight (line 235) | def addLight(self, p):
method render (line 238) | def render(self, canvas):
method rayColour (line 259) | def rayColour(self, ray):
method _lightIsVisible (line 275) | def _lightIsVisible(self, l, p):
method visibleLights (line 282) | def visibleLights(self, p):
function addColours (line 290) | def addColours(a, scale, b):
class SimpleSurface (line 294) | class SimpleSurface(object):
method __init__ (line 295) | def __init__(self, **kwargs):
method baseColourAt (line 303) | def baseColourAt(self, p):
method colourAt (line 306) | def colourAt(self, scene, ray, p, normal):
class CheckerboardSurface (line 330) | class CheckerboardSurface(SimpleSurface):
method __init__ (line 331) | def __init__(self, **kwargs):
method baseColourAt (line 336) | def baseColourAt(self, p):
function bench_raytrace (line 345) | def bench_raytrace(loops, width, height, filename):
function add_cmdline_args (line 366) | def add_cmdline_args(cmd, args):
function run_benchmark (line 373) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/raytrace_memray.py
class Vector (line 23) | class Vector(object):
method __init__ (line 24) | def __init__(self, initx, inity, initz):
method __str__ (line 29) | def __str__(self):
method __repr__ (line 32) | def __repr__(self):
method magnitude (line 35) | def magnitude(self):
method __add__ (line 38) | def __add__(self, other):
method __sub__ (line 44) | def __sub__(self, other):
method scale (line 48) | def scale(self, factor):
method dot (line 51) | def dot(self, other):
method cross (line 55) | def cross(self, other):
method normalized (line 63) | def normalized(self):
method negated (line 66) | def negated(self):
method __eq__ (line 69) | def __eq__(self, other):
method isVector (line 72) | def isVector(self):
method isPoint (line 75) | def isPoint(self):
method mustBeVector (line 78) | def mustBeVector(self):
method mustBePoint (line 81) | def mustBePoint(self):
method reflectThrough (line 84) | def reflectThrough(self, normal):
class Point (line 98) | class Point(object):
method __init__ (line 99) | def __init__(self, initx, inity, initz):
method __str__ (line 104) | def __str__(self):
method __repr__ (line 107) | def __repr__(self):
method __add__ (line 110) | def __add__(self, other):
method __sub__ (line 114) | def __sub__(self, other):
method isVector (line 120) | def isVector(self):
method isPoint (line 123) | def isPoint(self):
method mustBeVector (line 126) | def mustBeVector(self):
method mustBePoint (line 129) | def mustBePoint(self):
class Sphere (line 133) | class Sphere(object):
method __init__ (line 134) | def __init__(self, centre, radius):
method __repr__ (line 139) | def __repr__(self):
method intersectionTime (line 142) | def intersectionTime(self, ray):
method normalAt (line 151) | def normalAt(self, p):
class Halfspace (line 155) | class Halfspace(object):
method __init__ (line 156) | def __init__(self, point, normal):
method __repr__ (line 160) | def __repr__(self):
method intersectionTime (line 163) | def intersectionTime(self, ray):
method normalAt (line 170) | def normalAt(self, p):
class Ray (line 174) | class Ray(object):
method __init__ (line 175) | def __init__(self, point, vector):
method __repr__ (line 179) | def __repr__(self):
method pointAtTime (line 182) | def pointAtTime(self, t):
class Canvas (line 189) | class Canvas(object):
method __init__ (line 190) | def __init__(self, width, height):
method plot (line 197) | def plot(self, x, y, r, g, b):
method write_ppm (line 203) | def write_ppm(self, filename):
function firstIntersection (line 210) | def firstIntersection(intersections):
class Scene (line 220) | class Scene(object):
method __init__ (line 221) | def __init__(self):
method moveTo (line 229) | def moveTo(self, p):
method lookAt (line 232) | def lookAt(self, p):
method addObject (line 235) | def addObject(self, object, surface):
method addLight (line 238) | def addLight(self, p):
method render (line 241) | def render(self, canvas):
method rayColour (line 262) | def rayColour(self, ray):
method _lightIsVisible (line 278) | def _lightIsVisible(self, l, p):
method visibleLights (line 285) | def visibleLights(self, p):
function addColours (line 293) | def addColours(a, scale, b):
class SimpleSurface (line 297) | class SimpleSurface(object):
method __init__ (line 298) | def __init__(self, **kwargs):
method baseColourAt (line 306) | def baseColourAt(self, p):
method colourAt (line 309) | def colourAt(self, scene, ray, p, normal):
class CheckerboardSurface (line 333) | class CheckerboardSurface(SimpleSurface):
method __init__ (line 334) | def __init__(self, **kwargs):
method baseColourAt (line 339) | def baseColourAt(self, p):
function bench_raytrace (line 348) | def bench_raytrace(loops, width, height, filename):
function add_cmdline_args (line 377) | def add_cmdline_args(cmd, args):
FILE: benchmarks/benchmarking/cases/regex_dna_base.py
function make_cumulative (line 45) | def make_cumulative(table):
function repeat_fasta (line 56) | def repeat_fasta(src, n, nprint):
function random_fasta (line 84) | def random_fasta(table, n, seed, nprint):
function init_benchmarks (line 134) | def init_benchmarks(n, rng_seed):
function run_benchmarks (line 178) | def run_benchmarks(seq):
function bench_regex_dna (line 194) | def bench_regex_dna(loops, seq, expected_res):
function run_benchmark (line 204) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/regex_dna_memray.py
function make_cumulative (line 48) | def make_cumulative(table):
function repeat_fasta (line 59) | def repeat_fasta(src, n, nprint):
function random_fasta (line 87) | def random_fasta(table, n, seed, nprint):
function init_benchmarks (line 137) | def init_benchmarks(n, rng_seed):
function run_benchmarks (line 181) | def run_benchmarks(seq):
function bench_regex_dna (line 197) | def bench_regex_dna(loops, seq, expected_res):
function add_cmdline_args (line 212) | def add_cmdline_args(cmd, args):
FILE: benchmarks/benchmarking/cases/regex_effbot_base.py
function re_compile (line 20) | def re_compile(s):
function gen_regex_table (line 32) | def gen_regex_table():
function gen_string_table (line 58) | def gen_string_table(n):
function init_benchmarks (line 96) | def init_benchmarks(n_values=None):
function bench_regex_effbot (line 128) | def bench_regex_effbot(loops):
function run_benchmark (line 155) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/regex_effbot_memray.py
function re_compile (line 23) | def re_compile(s):
function gen_regex_table (line 35) | def gen_regex_table():
function gen_string_table (line 61) | def gen_string_table(n):
function init_benchmarks (line 99) | def init_benchmarks(n_values=None):
function bench_regex_effbot (line 131) | def bench_regex_effbot(loops):
function add_cmdline_args (line 163) | def add_cmdline_args(cmd, args):
FILE: benchmarks/benchmarking/cases/regex_v8_base.py
function block0 (line 285) | def block0():
function block1 (line 367) | def block1():
function block2 (line 445) | def block2():
function block3 (line 511) | def block3():
function block4 (line 633) | def block4():
function block5 (line 709) | def block5():
function block6 (line 767) | def block6():
function block7 (line 858) | def block7():
function block8 (line 933) | def block8():
function block9 (line 1020) | def block9():
function block10 (line 1236) | def block10():
function block11 (line 1394) | def block11():
function bench_regex_v8 (line 1875) | def bench_regex_v8(loops):
function run_benchmark (line 1891) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/regex_v8_memray.py
function block0 (line 288) | def block0():
function block1 (line 370) | def block1():
function block2 (line 448) | def block2():
function block3 (line 514) | def block3():
function block4 (line 636) | def block4():
function block5 (line 712) | def block5():
function block6 (line 770) | def block6():
function block7 (line 861) | def block7():
function block8 (line 936) | def block8():
function block9 (line 1023) | def block9():
function block10 (line 1239) | def block10():
function block11 (line 1397) | def block11():
function bench_regex_v8 (line 1878) | def bench_regex_v8(loops):
FILE: benchmarks/benchmarking/cases/spectral_norm_base.py
function eval_A (line 19) | def eval_A(i, j):
function eval_times_u (line 23) | def eval_times_u(func, u):
function eval_AtA_times_u (line 27) | def eval_AtA_times_u(u):
function part_A_times_u (line 31) | def part_A_times_u(i_u):
function part_At_times_u (line 39) | def part_At_times_u(i_u):
function bench_spectral_norm (line 47) | def bench_spectral_norm(loops):
function run_benchmark (line 63) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/spectral_norm_memray.py
function eval_A (line 22) | def eval_A(i, j):
function eval_times_u (line 26) | def eval_times_u(func, u):
function eval_AtA_times_u (line 30) | def eval_AtA_times_u(u):
function part_A_times_u (line 34) | def part_A_times_u(i_u):
function part_At_times_u (line 42) | def part_At_times_u(i_u):
function bench_spectral_norm (line 50) | def bench_spectral_norm(loops):
FILE: benchmarks/benchmarking/cases/sqlite_synth_base.py
class AvgLength (line 13) | class AvgLength(object):
method __init__ (line 14) | def __init__(self):
method step (line 18) | def step(self, x):
method finalize (line 23) | def finalize(self):
function bench_sqlite (line 27) | def bench_sqlite(loops):
function run_benchmark (line 46) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/sqlite_synth_memray.py
class AvgLength (line 16) | class AvgLength(object):
method __init__ (line 17) | def __init__(self):
method step (line 21) | def step(self, x):
method finalize (line 26) | def finalize(self):
function bench_sqlite (line 30) | def bench_sqlite(loops):
FILE: benchmarks/benchmarking/cases/telco_base.py
function rel_path (line 26) | def rel_path(*path):
function bench_telco (line 33) | def bench_telco(loops, filename):
function run_benchmark (line 84) | def run_benchmark():
FILE: benchmarks/benchmarking/cases/telco_memray.py
function rel_path (line 28) | def rel_path(*path):
function bench_telco (line 35) | def bench_telco(loops, filename):
function add_cmdline_args (line 90) | def add_cmdline_args(cmd, args):
FILE: benchmarks/benchmarking/plot.py
function get_data (line 13) | def get_data(result) -> Dict[str, Any]:
function remove_outliers (line 30) | def remove_outliers(values, m=2):
function plot_diff_pair (line 34) | def plot_diff_pair(ax, ref, head, names, outlier_rejection=True):
function formatter (line 69) | def formatter(val, pos):
function plot_diff (line 73) | def plot_diff(ref, head, output_filename: Path, title: str) -> None:
FILE: benchmarks/benchmarks.py
class TracebackBenchmarks (line 24) | class TracebackBenchmarks:
method setup (line 25) | def setup(self):
method time_get_stack_trace (line 46) | def time_get_stack_trace(self):
class AllocatorBenchmarks (line 50) | class AllocatorBenchmarks:
method setup (line 51) | def setup(self):
method time_malloc (line 55) | def time_malloc(self):
method time_posix_memalign (line 62) | def time_posix_memalign(self):
method time_posix_realloc (line 69) | def time_posix_realloc(self):
method time_calloc (line 76) | def time_calloc(self):
method time_pvalloc (line 83) | def time_pvalloc(self):
method time_valloc (line 90) | def time_valloc(self):
method time_realloc (line 97) | def time_realloc(self):
method time_mmap (line 104) | def time_mmap(self):
class ParserBenchmarks (line 112) | class ParserBenchmarks:
method setup (line 113) | def setup(self):
method time_end_to_end_parsing (line 123) | def time_end_to_end_parsing(self):
function recursive (line 127) | def recursive(n, chunk_size):
class HighWatermarkBenchmarks (line 144) | class HighWatermarkBenchmarks:
method setup (line 145) | def setup(self):
method time_high_watermark (line 153) | def time_high_watermark(self):
class MacroBenchmarksBase (line 161) | class MacroBenchmarksBase:
method __init_subclass__ (line 162) | def __init_subclass__(cls) -> None:
method bench_async_tree_cpu (line 168) | def bench_async_tree_cpu(self):
method bench_async_tree_io (line 172) | def bench_async_tree_io(self):
method bench_async_tree_memoization (line 176) | def bench_async_tree_memoization(self):
method bench_async_tree_cpu_io_mixed (line 180) | def bench_async_tree_cpu_io_mixed(self):
method bench_fannkuch (line 184) | def bench_fannkuch(self):
method bench_mdp (line 188) | def bench_mdp(self):
method bench_pprint_format (line 192) | def bench_pprint_format(self):
method bench_raytrace (line 196) | def bench_raytrace(self):
class MacroBenchmarksDefault (line 201) | class MacroBenchmarksDefault(MacroBenchmarksBase):
method setup (line 202) | def setup(self):
class MacroBenchmarksPythonAllocators (line 208) | class MacroBenchmarksPythonAllocators(MacroBenchmarksBase):
method setup (line 209) | def setup(self):
class MacroBenchmarksPythonNative (line 215) | class MacroBenchmarksPythonNative(MacroBenchmarksBase):
method setup (line 216) | def setup(self):
class MacroBenchmarksPythonAll (line 222) | class MacroBenchmarksPythonAll(MacroBenchmarksBase):
method setup (line 223) | def setup(self):
class FileSizeBenchmarks (line 229) | class FileSizeBenchmarks:
method setup (line 230) | def setup(self):
method track_async_tree_cpu (line 235) | def track_async_tree_cpu(self):
method track_async_tree_io (line 240) | def track_async_tree_io(self):
method track_async_tree_memoization (line 245) | def track_async_tree_memoization(self):
method track_async_tree_cpu_io_mixed (line 250) | def track_async_tree_cpu_io_mixed(self):
method track_fannkuch (line 255) | def track_fannkuch(self):
method track_mdp (line 260) | def track_mdp(self):
method track_pprint_format (line 265) | def track_pprint_format(self):
method track_raytrace (line 270) | def track_raytrace(self):
FILE: docs/_static/js/custom.js
function reveal (line 1) | function reveal() {
FILE: docs/examples/fibonacci/fib.py
function fib1 (line 4) | def fib1(n):
function fib2 (line 11) | def fib2(n, cache={0: 0, 1: 1}):
function run (line 18) | def run():
FILE: docs/examples/mandelbrot/mandelbrot-threaded.py
function mandelbrot (line 6) | def mandelbrot(height, width, x=-0.5, y=0, zoom=1, max_iterations=100):
FILE: docs/examples/mandelbrot/mandelbrot.py
function mandelbrot (line 4) | def mandelbrot(height, width, x=-0.5, y=0, zoom=1, max_iterations=100):
FILE: docs/examples/nbody/example.py
function rand_powerlaw (line 46) | def rand_powerlaw(slope, min_v, max_v):
function rand_uniform (line 53) | def rand_uniform(minimum, maximum):
function rand_rayleigh (line 57) | def rand_rayleigh(sigma):
FILE: docs/examples/sqlite/example.py
function generate_values (line 24) | def generate_values(count=100):
function generate_values_list (line 43) | def generate_values_list(symbols=1000, count=100):
function main (line 50) | def main():
FILE: docs/tutorials/exercise_1/fibonacci.py
function fibonacci (line 6) | def fibonacci(length):
function generate_fibonacci_hash (line 23) | def generate_fibonacci_hash(length_1, length_2, length_3):
FILE: docs/tutorials/exercise_2/holding_onto_memory.py
function load_xMb_of_data (line 14) | def load_xMb_of_data(mb: int) -> np.ndarray:
function duplicate_data (line 19) | def duplicate_data(data: np.ndarray) -> np.ndarray:
function add_scalar (line 23) | def add_scalar(data: np.ndarray, scalar: int) -> np.ndarray:
function subtract_scalar (line 27) | def subtract_scalar(data: np.ndarray, scalar: int) -> np.ndarray:
function raise_to_power (line 31) | def raise_to_power(data: np.ndarray, power: int) -> np.ndarray:
function process_data (line 35) | def process_data() -> np.ndarray:
FILE: docs/tutorials/exercise_3/lru_cache.py
class Algorithms (line 12) | class Algorithms:
method __init__ (line 13) | def __init__(self, inc: int):
method factorial_plus (line 17) | def factorial_plus(self, n: int) -> int:
function generate_factorial_plus_last_digit (line 21) | def generate_factorial_plus_last_digit(plus_range: int, factorial_range:...
function compare_counts_different_factorials (line 28) | def compare_counts_different_factorials():
FILE: docs/tutorials/solutions/exercise_1/fibonacci.py
function fibonacci (line 6) | def fibonacci(length):
function generate_fibonacci_hash (line 23) | def generate_fibonacci_hash(length_1, length_2, length_3):
FILE: docs/tutorials/solutions/exercise_2/holding_onto_memory.py
function load_xMb_of_data (line 14) | def load_xMb_of_data(mb: int) -> np.ndarray:
function duplicate_data (line 19) | def duplicate_data(data: np.ndarray) -> np.ndarray:
function add_scalar (line 23) | def add_scalar(data: np.ndarray, scalar: int) -> np.ndarray:
function subtract_scalar (line 27) | def subtract_scalar(data: np.ndarray, scalar: int) -> np.ndarray:
function raise_to_power (line 31) | def raise_to_power(data: np.ndarray, power: int) -> np.ndarray:
function process_data_fix_1 (line 35) | def process_data_fix_1():
function process_data_fix_2 (line 48) | def process_data_fix_2():
FILE: docs/tutorials/solutions/exercise_3/lru_cache.py
class Algorithms (line 10) | class Algorithms:
method __init__ (line 11) | def __init__(self, inc: int):
method _uncached_factorial_plus (line 15) | def _uncached_factorial_plus(self, n: int) -> int:
function generate_factorial_plus_last_digit (line 19) | def generate_factorial_plus_last_digit(plus_range: int, factorial_range:...
function compare_counts_different_factorials (line 26) | def compare_counts_different_factorials():
FILE: docs/tutorials/tests/test_exercise_1.py
function test_fibonacci (line 8) | def test_fibonacci():
function test_fibonacci_empty (line 21) | def test_fibonacci_empty():
function test_fibonacci_short (line 34) | def test_fibonacci_short(length, expected):
function test_fibonacci_multiple (line 47) | def test_fibonacci_multiple(length, expected):
function test_hash_modulo_10000 (line 52) | def test_hash_modulo_10000():
FILE: docs/tutorials/tests/test_exercise_2.py
function test_holding_in_memory (line 7) | def test_holding_in_memory():
function test_result (line 11) | def test_result():
FILE: docs/tutorials/tests/test_exercise_3.py
function test_lru_cache (line 12) | def test_lru_cache():
function test_algorithms_0 (line 20) | def test_algorithms_0(value):
function test_algorithms_5 (line 25) | def test_algorithms_5():
function test_generate_factorial_plus_last_digit_0 (line 35) | def test_generate_factorial_plus_last_digit_0():
function test_generate_factorial_plus_0_last_digit (line 40) | def test_generate_factorial_plus_0_last_digit():
function test_generate_factorial_plus (line 51) | def test_generate_factorial_plus():
FILE: setup.py
class BuildMemray (line 38) | class BuildMemray(build_ext_orig):
method run (line 39) | def run(self):
method announce_and_run (line 44) | def announce_and_run(self, command, **kwargs):
method build_libbacktrace (line 51) | def build_libbacktrace(self):
method build_js_files (line 83) | def build_js_files(self):
FILE: src/memray/_destination.py
class Destination (line 7) | class Destination:
class FileDestination (line 12) | class FileDestination(Destination):
class SocketDestination (line 28) | class SocketDestination(Destination):
FILE: src/memray/_errors.py
class MemrayError (line 4) | class MemrayError(Exception):
class MemrayCommandError (line 8) | class MemrayCommandError(MemrayError):
method __init__ (line 11) | def __init__(self, *args: Any, exit_code: int) -> None:
FILE: src/memray/_ipython/__init__.py
function load_ipython_extension (line 4) | def load_ipython_extension(ipython: Any) -> None:
FILE: src/memray/_ipython/flamegraph.py
function _run_cell (line 36) | def _run_cell(shell: Any, code: str) -> None:
function _display_iframe (line 41) | def _display_iframe(frame: IFrame) -> None:
function argument_parser (line 46) | def argument_parser() -> argparse.ArgumentParser:
class FlamegraphMagics (line 135) | class FlamegraphMagics(Magics):
method memray_flamegraph (line 137) | def memray_flamegraph(self, line: str, cell: str) -> None:
FILE: src/memray/_memray.pyi
function set_log_level (line 31) | def set_log_level(level: int) -> None: ...
class AllocationRecord (line 33) | class AllocationRecord:
method address (line 35) | def address(self) -> int: ...
method allocator (line 37) | def allocator(self) -> int: ...
method n_allocations (line 39) | def n_allocations(self) -> int: ...
method size (line 41) | def size(self) -> int: ...
method stack_id (line 43) | def stack_id(self) -> int: ...
method tid (line 45) | def tid(self) -> int: ...
method native_stack_id (line 47) | def native_stack_id(self) -> int: ...
method native_segment_generation (line 49) | def native_segment_generation(self) -> int: ...
method thread_name (line 51) | def thread_name(self) -> str: ...
method hybrid_stack_trace (line 52) | def hybrid_stack_trace(
method native_stack_trace (line 56) | def native_stack_trace(
method stack_trace (line 59) | def stack_trace(
method __eq__ (line 62) | def __eq__(self, other: Any) -> Any: ...
method __ge__ (line 63) | def __ge__(self, other: Any) -> Any: ...
method __gt__ (line 64) | def __gt__(self, other: Any) -> Any: ...
method __hash__ (line 65) | def __hash__(self) -> Any: ...
method __le__ (line 66) | def __le__(self, other: Any) -> Any: ...
method __lt__ (line 67) | def __lt__(self, other: Any) -> Any: ...
method __ne__ (line 68) | def __ne__(self, other: Any) -> Any: ...
class TrackedObjectRecord (line 70) | class TrackedObjectRecord:
method tid (line 72) | def tid(self) -> int: ...
method address (line 74) | def address(self) -> int: ...
method is_created (line 76) | def is_created(self) -> bool: ...
method frame_index (line 78) | def frame_index(self) -> int: ...
method native_frame_id (line 80) | def native_frame_id(self) -> int: ...
method native_segment_generation (line 82) | def native_segment_generation(self) -> int: ...
method toPythonObject (line 83) | def toPythonObject(self) -> Any: ...
method hybrid_stack_trace (line 84) | def hybrid_stack_trace(
method native_stack_trace (line 88) | def native_stack_trace(
method stack_trace (line 91) | def stack_trace(
method __eq__ (line 94) | def __eq__(self, other: Any) -> Any: ...
method __hash__ (line 95) | def __hash__(self) -> Any: ...
method __repr__ (line 96) | def __repr__(self) -> str: ...
method __str__ (line 97) | def __str__(self) -> str: ...
class Interval (line 99) | class Interval:
method __init__ (line 100) | def __init__(
method __eq__ (line 107) | def __eq__(self, other: Any) -> Any: ...
class TemporalAllocationRecord (line 113) | class TemporalAllocationRecord:
method allocator (line 115) | def allocator(self) -> int: ...
method stack_id (line 117) | def stack_id(self) -> int: ...
method tid (line 119) | def tid(self) -> int: ...
method native_stack_id (line 121) | def native_stack_id(self) -> int: ...
method native_segment_generation (line 123) | def native_segment_generation(self) -> int: ...
method thread_name (line 125) | def thread_name(self) -> str: ...
method hybrid_stack_trace (line 126) | def hybrid_stack_trace(
method native_stack_trace (line 130) | def native_stack_trace(
method stack_trace (line 133) | def stack_trace(
method __eq__ (line 136) | def __eq__(self, other: Any) -> Any: ...
method __hash__ (line 137) | def __hash__(self) -> Any: ...
class AllocatorType (line 140) | class AllocatorType(enum.IntEnum):
class FileFormat (line 157) | class FileFormat(enum.IntEnum):
function start_thread_trace (line 161) | def start_thread_trace(frame: FrameType, event: str, arg: Any) -> None: ...
class FileReader (line 163) | class FileReader:
method metadata (line 165) | def metadata(self) -> Metadata: ...
method __init__ (line 166) | def __init__(
method get_allocation_records (line 173) | def get_allocation_records(self) -> Iterable[AllocationRecord]: ...
method get_temporal_allocation_records (line 174) | def get_temporal_allocation_records(
method get_temporal_high_water_mark_allocation_records (line 178) | def get_temporal_high_water_mark_allocation_records(
method get_high_watermark_allocation_records (line 182) | def get_high_watermark_allocation_records(
method get_leaked_allocation_records (line 186) | def get_leaked_allocation_records(
method get_temporary_allocation_records (line 189) | def get_temporary_allocation_records(
method get_memory_snapshots (line 192) | def get_memory_snapshots(self) -> Iterable[MemorySnapshot]: ...
method __enter__ (line 193) | def __enter__(self) -> Any: ...
method __exit__ (line 194) | def __exit__(
method closed (line 201) | def closed(self) -> bool: ...
method close (line 202) | def close(self) -> None: ...
method get_tracked_objects (line 203) | def get_tracked_objects(
function compute_statistics (line 207) | def compute_statistics(
function dump_all_records (line 213) | def dump_all_records(file_name: Union[str, Path]) -> None: ...
class SocketReader (line 215) | class SocketReader:
method __init__ (line 216) | def __init__(self, port: int) -> None: ...
method __enter__ (line 217) | def __enter__(self) -> "SocketReader": ...
method __exit__ (line 218) | def __exit__(
method get_current_snapshot (line 224) | def get_current_snapshot(
method command_line (line 228) | def command_line(self) -> Optional[str]: ...
method is_active (line 230) | def is_active(self) -> bool: ...
method pid (line 232) | def pid(self) -> Optional[int]: ...
method has_native_traces (line 234) | def has_native_traces(self) -> bool: ...
class Tracker (line 236) | class Tracker:
method reader (line 238) | def reader(self) -> FileReader: ...
method __init__ (line 240) | def __init__(
method __init__ (line 253) | def __init__(
method __enter__ (line 264) | def __enter__(self) -> Any: ...
method __exit__ (line 265) | def __exit__(
method get_surviving_objects (line 271) | def get_surviving_objects(self) -> list[object]: ...
function greenlet_trace (line 273) | def greenlet_trace(event: str, args: Any) -> None: ...
class PymallocDomain (line 275) | class PymallocDomain(enum.IntEnum):
function size_fmt (line 280) | def size_fmt(num: int, suffix: str = "B") -> str: ...
class SymbolicSupport (line 282) | class SymbolicSupport(enum.IntEnum):
function get_symbolic_support (line 287) | def get_symbolic_support() -> SymbolicSupport: ...
class HighWaterMarkAggregatorTestHarness (line 292) | class HighWaterMarkAggregatorTestHarness:
method add_allocation (line 293) | def add_allocation(
method capture_snapshot (line 303) | def capture_snapshot(self) -> None: ...
method high_water_mark_bytes_by_snapshot (line 304) | def high_water_mark_bytes_by_snapshot(self) -> list[int]: ...
method get_current_heap_size (line 305) | def get_current_heap_size(self) -> int: ...
method get_temporal_allocations (line 306) | def get_temporal_allocations(self) -> list[TemporalAllocationRecord]: ...
method get_allocations (line 307) | def get_allocations(self) -> list[dict[str, int]]: ...
class AllocationLifetimeAggregatorTestHarness (line 309) | class AllocationLifetimeAggregatorTestHarness:
method add_allocation (line 310) | def add_allocation(
method capture_snapshot (line 320) | def capture_snapshot(self) -> None: ...
method get_allocations (line 321) | def get_allocations(self) -> list[TemporalAllocationRecord]: ...
class Segment (line 323) | class Segment(TypedDict):
class Mapping (line 327) | class Mapping(TypedDict):
class RecordWriterTestHarness (line 332) | class RecordWriterTestHarness:
method __init__ (line 333) | def __init__(
method write_header (line 343) | def write_header(self, seek_to_start: bool) -> None: ...
method write_memory_record (line 344) | def write_memory_record(self, ms_since_epoch: int, rss: int) -> bool: ...
method write_code_object (line 345) | def write_code_object(
method write_unresolved_native_frame (line 353) | def write_unresolved_native_frame(self, ip: int, index: int) -> bool: ...
method write_allocation_record (line 354) | def write_allocation_record(
method write_frame_push (line 362) | def write_frame_push(
method write_frame_pop (line 369) | def write_frame_pop(self, tid: int, count: int) -> bool: ...
method write_thread_record (line 370) | def write_thread_record(self, tid: int, name: str) -> bool: ...
method write_mappings (line 371) | def write_mappings(self, mappings: list[Mapping]) -> bool: ...
method write_trailer (line 372) | def write_trailer(self) -> bool: ...
method get_linetable (line 374) | def get_linetable(code_object: CodeType) -> bytes: ...
method get_lasti (line 376) | def get_lasti(frame_object: FrameType) -> int: ...
FILE: src/memray/_memray/compat.cpp
type memray::compat (line 3) | namespace memray::compat {
function setprofileAllThreads (line 5) | void
type _PyCodeLocationInfoKind (line 47) | enum _PyCodeLocationInfoKind {
function parseLinetable311 (line 59) | inline bool
function parseLinetable310 (line 136) | inline bool
function parseLinetable39 (line 166) | inline bool
function parseLinetable (line 191) | bool
FILE: src/memray/_memray/compat.h
function namespace (line 10) | namespace memray::compat {
FILE: src/memray/_memray/elf_shenanigans.cpp
type elf_patcher_context_t (line 17) | struct elf_patcher_context_t
type memray::linker (line 26) | namespace memray::linker {
function unprotect_page (line 30) | static inline int
function patch_symbol (line 39) | static void
function overwrite_elf_table (line 62) | static void
function Sxword (line 101) | static Sxword
function patch_symbols (line 118) | static void
function phdrs_callback (line 160) | static int
FILE: src/memray/_memray/elf_utils.h
type bloom_el_t (line 19) | typedef uint64_t bloom_el_t;
type bloom_el_t (line 26) | typedef uint32_t bloom_el_t;
function explicit (line 61) | explicit DynamicInfoTable(const Addr base, const Dyn* dynamic_section)
function T (line 73) | T* begin() const noexcept
function T (line 78) | T* end() const noexcept
function isDefinedGlobalSymbol (line 89) | struct SymbolTable
function getSymbolAddress (line 130) | uintptr_t getSymbolAddress(const char* name) const
function findSymbolByElfHashTable (line 148) | uintptr_t findSymbolByElfHashTable(const char* name, const ElfW(Dyn) * d...
function findSymbolByGNUHashTable (line 181) | uintptr_t findSymbolByGNUHashTable(const char* name, const ElfW(Dyn) * d...
FILE: src/memray/_memray/exceptions.h
function namespace (line 5) | namespace memray::exception {
FILE: src/memray/_memray/frame_tree.h
function namespace (line 6) | namespace memray::tracking_api {
function getTraceIndex (line 40) | size_t getTraceIndex(index_t parent_index, frame_id_t frame)
type DescendentEdge (line 61) | struct DescendentEdge
type Node (line 72) | struct Node
FILE: src/memray/_memray/hooks.cpp
type memray::hooks (line 9) | namespace memray::hooks {
function phdr_symfind_callback (line 12) | int
function AllocatorKind (line 48) | AllocatorKind
function isDeallocator (line 79) | bool
function ensureAllHooksAreValid (line 97) | void
type memray::intercept (line 107) | namespace memray::intercept {
function pymalloc_free (line 153) | void
function free (line 182) | void
function munmap (line 266) | int
function posix_memalign (line 293) | int
function dlclose (line 392) | int
function prctl (line 459) | int
function PyGILState_STATE (line 481) | PyGILState_STATE
function pyreftracer (line 489) | int
FILE: src/memray/_memray/hooks.h
type symbol_query (line 58) | struct symbol_query
function explicit (line 77) | explicit SymbolHook(const char* symbol, signature_t original)
function symbol_query (line 86) | symbol_query query{0, d_symbol, nullptr};
type class (line 121) | enum class
function AllocatorKind (line 140) | enum class AllocatorKind {
function namespace (line 163) | namespace memray::intercept {
FILE: src/memray/_memray/inject.cpp
type PyObject (line 16) | struct PyObject
type memray (line 39) | namespace memray {
function connect_client (line 42) | int
function sendall (line 78) | bool
function recvall (line 94) | bool
function Memray_PyErr_ToString (line 113) | std::string
function run_script_impl (line 151) | bool
function run_script (line 200) | bool
function run_client (line 215) | void
function memray_spawn_client (line 255) | __attribute__((visibility("default"))) int
FILE: src/memray/_memray/linker_shenanigans.h
function namespace (line 8) | namespace memray::linker {
FILE: src/memray/_memray/logging.cpp
type memray (line 6) | namespace memray {
function setLogThreshold (line 21) | void
function logLevel (line 27) | logLevel
function logToStderr (line 33) | void
FILE: src/memray/_memray/logging.h
function namespace (line 7) | namespace memray {
FILE: src/memray/_memray/lz4_stream.h
function namespace (line 46) | namespace lz4_stream {
FILE: src/memray/_memray/macho_shenanigans.cpp
type memray::linker (line 13) | namespace memray::linker {
function patch_symbol (line 16) | static void
function patch_symbols_in_section (line 52) | static void
function lazy_pointer_from_stub (line 83) | static uint64_t
function patch_stubs (line 224) | static void
function patch_symbols_in_shared_object (line 268) | static void
function patch_symbols_in_all_shared_objects (line 367) | static void
FILE: src/memray/_memray/macho_utils.h
type mach_header_t (line 23) | typedef struct mach_header_64 mach_header_t;
type segment_command_t (line 24) | typedef struct segment_command_64 segment_command_t;
type section_t (line 25) | typedef struct section_64 section_t;
type nlist_t (line 26) | typedef struct nlist_64 nlist_t;
type mach_header_t (line 29) | typedef struct mach_header mach_header_t;
type segment_command_t (line 30) | typedef struct segment_command segment_command_t;
type section_t (line 31) | typedef struct section section_t;
type nlist_t (line 32) | typedef struct nlist nlist_t;
function if (line 44) | struct DynamicInfoTable
FILE: src/memray/_memray/native_resolver.cpp
type memray::native_resolver (line 9) | namespace memray::native_resolver {
function demangle (line 69) | static std::string
type CallbackData (line 94) | struct CallbackData
function InternedString (line 190) | InternedString
function PyObject (line 221) | PyObject*
function findModule (line 267) | static auto
function backtrace_state (line 370) | backtrace_state*
function unwindHere (line 463) | std::vector<std::string>
FILE: src/memray/_memray/native_resolver.h
type Frame (line 49) | struct Frame
function start (line 67) | uintptr_t start() const;
FILE: src/memray/_memray/python_helpers.cpp
type memray::python_helpers (line 3) | namespace memray::python_helpers {
function PyObject (line 4) | PyObject*
FILE: src/memray/_memray/python_helpers.h
function namespace (line 11) | namespace memray::python_helpers {
FILE: src/memray/_memray/record_reader.cpp
type memray::api (line 19) | namespace memray::api {
function Location (line 631) | Location
function PyObject (line 931) | PyObject*
function PyObject (line 937) | PyObject*
function PyObject (line 984) | PyObject*
function PyObject (line 1041) | PyObject*
function HeaderRecord (line 1056) | HeaderRecord
function thread_id_t (line 1062) | thread_id_t
function Allocation (line 1084) | Allocation
function MemoryRecord (line 1090) | MemoryRecord
function AggregatedAllocation (line 1096) | AggregatedAllocation
function MemorySnapshot (line 1102) | MemorySnapshot
function TrackedObject (line 1108) | TrackedObject
function PyObject (line 1114) | PyObject*
function PyObject (line 1184) | PyObject*
function PyObject (line 1358) | PyObject*
FILE: src/memray/_memray/record_reader.h
function namespace (line 22) | namespace memray::api {
FILE: src/memray/_memray/record_writer.cpp
type memray::tracking_api (line 22) | namespace memray::tracking_api {
function PythonAllocatorType (line 26) | static PythonAllocatorType
class StreamingRecordWriter (line 60) | class StreamingRecordWriter : public RecordWriter
method StreamingRecordWriter (line 70) | StreamingRecordWriter(StreamingRecordWriter& other) = delete;
method StreamingRecordWriter (line 71) | StreamingRecordWriter(StreamingRecordWriter&& other) = delete;
class AggregatingRecordWriter (line 123) | class AggregatingRecordWriter : public RecordWriter
method AggregatingRecordWriter (line 133) | AggregatingRecordWriter(StreamingRecordWriter& other) = delete;
method AggregatingRecordWriter (line 134) | AggregatingRecordWriter(StreamingRecordWriter&& other) = delete;
function createRecordWriter (line 177) | std::unique_ptr<RecordWriter>
FILE: src/memray/_memray/record_writer.h
function namespace (line 10) | namespace memray::tracking_api {
FILE: src/memray/_memray/records.cpp
type memray::tracking_api (line 7) | namespace memray::tracking_api {
function PyObject (line 11) | PyObject*
function Allocation (line 58) | Allocation
function Allocation (line 73) | Allocation
function PyObject (line 88) | PyObject*
function PyObject (line 116) | PyObject*
FILE: src/memray/_memray/records.h
function namespace (line 18) | namespace memray::tracking_api {
FILE: src/memray/_memray/sink.cpp
type memray::io (line 19) | namespace memray::io {
function posix_fallocate (line 26) | static int
function removeSuffix (line 44) | std::string
type sockaddr_storage (line 332) | struct sockaddr_storage
type sockaddr (line 369) | struct sockaddr
FILE: src/memray/_memray/sink.h
function class (line 12) | class Sink
function d_compress (line 47) | bool d_compress{1}
function d_fileSize (line 49) | size_t d_fileSize{0}
function d_bufferOffset (line 51) | size_t d_bufferOffset{0}
function class (line 88) | class NullSink : public Sink
FILE: src/memray/_memray/snapshot.cpp
type memray::api (line 6) | namespace memray::api {
function reduced_snapshot_map_t (line 138) | reduced_snapshot_map_t
function reduced_snapshot_map_t (line 224) | reduced_snapshot_map_t
function reduced_snapshot_map_t (line 256) | reduced_snapshot_map_t
function UsageHistory (line 289) | UsageHistory&
function Contribution (line 399) | Contribution
function Contribution (line 427) | Contribution
function HighWaterMarkLocationKey (line 719) | HighWaterMarkLocationKey
type KeyHash (line 772) | struct KeyHash
function reduced_snapshot_map_t (line 840) | static reduced_snapshot_map_t
function HighWatermark (line 900) | HighWatermark
function PyObject (line 930) | PyObject*
function PyObject (line 950) | PyObject*
FILE: src/memray/_memray/snapshot.h
function namespace (line 16) | namespace memray::api {
type std (line 498) | typedef std::unordered_map<std::optional<frame_id_t>, SizeAndCount> Size...
function d_total_allocations (line 504) | uint64_t d_total_allocations{}
function d_total_bytes_allocated (line 505) | uint64_t d_total_bytes_allocated{}
FILE: src/memray/_memray/socket_reader_thread.cpp
type memray::socket_thread (line 5) | namespace memray::socket_thread {
function PyObject (line 78) | PyObject*
FILE: src/memray/_memray/socket_reader_thread.h
function namespace (line 14) | namespace memray::socket_thread {
FILE: src/memray/_memray/source.cpp
type memray::io (line 21) | namespace memray::io {
type addrinfo (line 184) | struct addrinfo
type addrinfo (line 185) | struct addrinfo
type addrinfo (line 186) | struct addrinfo
FILE: src/memray/_memray/source.h
function class (line 15) | class Source
function class (line 25) | class FileSource : public Source
function d_sockfd (line 59) | int d_sockfd{-1};
FILE: src/memray/_memray/tracking_api.cpp
function get_executable (line 39) | std::string
function starts_with (line 52) | static bool
class StopTheWorldGuard (line 59) | class StopTheWorldGuard
method StopTheWorldGuard (line 62) | StopTheWorldGuard()
method StopTheWorldGuard (line 74) | StopTheWorldGuard(const StopTheWorldGuard&) = delete;
method StopTheWorldGuard (line 75) | StopTheWorldGuard& operator=(const StopTheWorldGuard&) = delete;
method StopTheWorldGuard (line 76) | StopTheWorldGuard(StopTheWorldGuard&&) = delete;
type memray::tracking_api (line 87) | namespace memray::tracking_api {
function thread_id_t (line 95) | static inline thread_id_t
function thread_id_t (line 104) | static inline thread_id_t
class PythonStackTracker (line 139) | class PythonStackTracker
method PythonStackTracker (line 142) | PythonStackTracker() = default;
class LazilyEmittedFrame (line 144) | class LazilyEmittedFrame
function PythonStackTracker (line 249) | PythonStackTracker&
method PythonStackTracker (line 142) | PythonStackTracker() = default;
class LazilyEmittedFrame (line 144) | class LazilyEmittedFrame
function PythonStackTracker (line 257) | PythonStackTracker&
method PythonStackTracker (line 142) | PythonStackTracker() = default;
class LazilyEmittedFrame (line 144) | class LazilyEmittedFrame
type StackCreator (line 437) | struct StackCreator
method StackCreator (line 441) | StackCreator()
type mach_task_basic_info (line 936) | struct mach_task_basic_info
function dl_iterate_phdr_callback (line 1200) | static int
type mach_header (line 1246) | struct mach_header
function code_object_id_t (line 1357) | code_object_id_t
function PyObject (line 1437) | PyObject*
function PyObject (line 1461) | PyObject*
function Tracker (line 1469) | Tracker*
function PyTraceFunction (line 1520) | int
function set_up_pthread_fork_handlers (line 1566) | void
function install_trace_function (line 1578) | void
FILE: src/memray/_memray/tracking_api.h
function RecursionGuard (line 46) | struct RecursionGuard
function initialize (line 64) | static void initialize()
function isActive (line 68) | static __attribute__((always_inline)) inline bool isActive()
function setValue (line 73) | static __attribute__((always_inline)) inline void setValue(bool value)
function initialize (line 80) | static void initialize()
function class (line 135) | class NativeTrace
function const (line 149) | auto end() const
function fill (line 161) | __attribute__((always_inline)) inline bool fill(size_t skip)
function setup (line 183) | static void setup()
function flushCache (line 200) | static inline void flushCache()
function prepareNativeTrace (line 295) | static inline bool prepareNativeTrace(std::optional<NativeTrace>& trace)
function trackDeallocation (line 313) | __attribute__((always_inline)) inline static void
function invalidate_module_cache (line 328) | __attribute__((always_inline)) inline static void invalidate_module_cache()
function registerThreadName (line 342) | __attribute__((always_inline)) inline static void registerThreadName(con...
function registerThreadNameById (line 356) | inline static void registerThreadNameById(uint64_t thread, const char* n...
FILE: src/memray/_metadata.py
class Metadata (line 12) | class Metadata:
FILE: src/memray/_stats.py
class Stats (line 7) | class Stats:
FILE: src/memray/_stats.pyi
class Stats (line 7) | class Stats:
FILE: src/memray/_test.py
class MemoryAllocator (line 18) | class MemoryAllocator:
method __init__ (line 19) | def __init__(self) -> None:
method free (line 22) | def free(self) -> None:
method malloc (line 25) | def malloc(self, size: int) -> bool:
method calloc (line 28) | def calloc(self, size: int) -> bool:
method realloc (line 31) | def realloc(self, size: int) -> bool:
method posix_memalign (line 34) | def posix_memalign(self, size: int) -> bool:
method aligned_alloc (line 37) | def aligned_alloc(self, size: int) -> bool:
method memalign (line 40) | def memalign(self, size: int) -> bool:
method valloc (line 43) | def valloc(self, size: int) -> bool:
method pvalloc (line 46) | def pvalloc(self, size: int) -> bool:
method run_in_pthread (line 49) | def run_in_pthread(self, callback: Callable[[], None]) -> None:
FILE: src/memray/_test_utils.pyi
class MemoryAllocator (line 5) | class MemoryAllocator:
method __init__ (line 6) | def __init__(self) -> None: ...
method free (line 7) | def free(self) -> None: ...
method malloc (line 8) | def malloc(self, size: int) -> bool: ...
method calloc (line 9) | def calloc(self, size: int) -> bool: ...
method realloc (line 10) | def realloc(self, size: int) -> bool: ...
method posix_memalign (line 11) | def posix_memalign(self, size: int) -> bool: ...
method aligned_alloc (line 12) | def aligned_alloc(self, size: int) -> bool: ...
method memalign (line 13) | def memalign(self, size: int) -> bool: ...
method valloc (line 14) | def valloc(self, size: int) -> bool: ...
method pvalloc (line 15) | def pvalloc(self, size: int) -> bool: ...
method run_in_pthread (line 16) | def run_in_pthread(self, callback: Callable[[], None]) -> None: ...
class PymallocMemoryAllocator (line 18) | class PymallocMemoryAllocator:
method __init__ (line 19) | def __init__(self, domain: PymallocDomain) -> None: ...
method free (line 20) | def free(self) -> None: ...
method malloc (line 21) | def malloc(self, size: int) -> None: ...
method calloc (line 22) | def calloc(self, size: int) -> None: ...
method realloc (line 23) | def realloc(self, size: int) -> None: ...
class MmapAllocator (line 25) | class MmapAllocator:
method __init__ (line 26) | def __init__(self, size: int, address: int = 0) -> None: ...
method address (line 28) | def address(self) -> int: ...
method munmap (line 29) | def munmap(self, length: int, offset: int = 0) -> None: ...
function _cython_nested_allocation (line 31) | def _cython_nested_allocation(
function _cython_allocate_in_two_places (line 34) | def _cython_allocate_in_two_places(size: int) -> None: ...
function set_thread_name (line 35) | def set_thread_name(name: str) -> int: ...
function function_caller (line 36) | def function_caller(func: Callable[[], None]) -> None: ...
function allocate_without_gil_held (line 37) | def allocate_without_gil_held(wake_up_main_fd: int, wake_up_thread_fd: i...
function allocate_cpp_vector (line 38) | def allocate_cpp_vector(size: int) -> int: ...
function fill_cpp_vector (line 39) | def fill_cpp_vector(size: int) -> int: ...
function exit (line 40) | def exit(py_finalize: bool = False) -> None: ...
class PrimeCaches (line 42) | class PrimeCaches:
method __init__ (line 43) | def __init__(self, size: int) -> None: ...
method __enter__ (line 44) | def __enter__(self) -> None: ...
method __exit__ (line 45) | def __exit__(self, *args: object) -> None: ...
FILE: src/memray/_thread_name_interceptor.py
class ThreadNameInterceptor (line 5) | class ThreadNameInterceptor:
method __init__ (line 14) | def __init__(self, attr: str, callback: Callable[[int, str], None]) ->...
method __set__ (line 18) | def __set__(self, instance: threading.Thread, value: object) -> None:
FILE: src/memray/commands/__init__.py
class Command (line 52) | class Command(Protocol):
method prepare_parser (line 53) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
method run (line 56) | def run(self, args: argparse.Namespace, parser: argparse.ArgumentParse...
function get_argument_parser (line 75) | def get_argument_parser() -> argparse.ArgumentParser:
function determine_logging_level_from_verbosity (line 118) | def determine_logging_level_from_verbosity(
function main (line 129) | def main(args: Optional[List[str]] = None) -> int:
FILE: src/memray/commands/attach.py
function debugger_inject (line 134) | def debugger_inject(debugger: str, pid: int, port: int, verbose: bool) -...
function remote_exec_inject (line 237) | def remote_exec_inject(pid: int, port: int, verbose: bool, tmpdir: str) ...
function inject (line 271) | def inject(method: str, pid: int, port: int, verbose: bool, tmpdir: str)...
function _sys_remote_exec_available (line 278) | def _sys_remote_exec_available(verbose: bool) -> bool:
function _gdb_available (line 286) | def _gdb_available(verbose: bool) -> bool:
function _lldb_available (line 294) | def _lldb_available(verbose: int) -> bool:
function debugger_available (line 322) | def debugger_available(debugger: str, verbose: bool = False) -> bool:
function recvall (line 330) | def recvall(sock: socket.socket) -> str:
class ErrorReaderThread (line 334) | class ErrorReaderThread(threading.Thread):
method __init__ (line 335) | def __init__(self, sock: socket.socket) -> None:
method run (line 339) | def run(self) -> None:
class _DebuggerCommand (line 353) | class _DebuggerCommand:
method prepare_parser (line 354) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
method resolve_debugger (line 376) | def resolve_debugger(self, method: str, *, verbose: bool = False) -> str:
method inject_control_channel (line 401) | def inject_control_channel(
class AttachCommand (line 426) | class AttachCommand(_DebuggerCommand):
method prepare_parser (line 429) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
method run (line 493) | def run(self, args: argparse.Namespace, parser: argparse.ArgumentParse...
class DetachCommand (line 582) | class DetachCommand(_DebuggerCommand):
method run (line 585) | def run(self, args: argparse.Namespace, parser: argparse.ArgumentParse...
FILE: src/memray/commands/common.py
class ReporterFactory (line 30) | class ReporterFactory(Protocol):
method __call__ (line 31) | def __call__(
class TemporalReporterFactory (line 42) | class TemporalReporterFactory(Protocol):
method __call__ (line 43) | def __call__(
function warn_if_not_enough_symbols (line 55) | def warn_if_not_enough_symbols() -> None:
function warn_if_file_is_not_aggregated_and_is_too_big (line 81) | def warn_if_file_is_not_aggregated_and_is_too_big(
class HighWatermarkCommand (line 99) | class HighWatermarkCommand:
method __init__ (line 100) | def __init__(
method determine_output_filename (line 113) | def determine_output_filename(self, results_file: pathlib.Path) -> pat...
method validate_filenames (line 120) | def validate_filenames(
method write_report (line 140) | def write_report(
method prepare_parser (line 226) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
method run (line 285) | def run(self, args: argparse.Namespace, parser: argparse.ArgumentParse...
FILE: src/memray/commands/flamegraph.py
class FlamegraphCommand (line 7) | class FlamegraphCommand(HighWatermarkCommand):
method __init__ (line 10) | def __init__(self) -> None:
method prepare_parser (line 17) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
FILE: src/memray/commands/live.py
class LiveCommand (line 10) | class LiveCommand:
method prepare_parser (line 13) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
method run (line 21) | def run(self, args: argparse.Namespace, parser: argparse.ArgumentParse...
method start_live_interface (line 25) | def start_live_interface(
FILE: src/memray/commands/parse.py
class ParseCommand (line 8) | class ParseCommand:
method prepare_parser (line 11) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
method run (line 14) | def run(self, args: argparse.Namespace, parser: argparse.ArgumentParse...
FILE: src/memray/commands/run.py
function _get_free_port (line 27) | def _get_free_port() -> int:
function _should_modify_sys_path (line 34) | def _should_modify_sys_path() -> bool:
function _run_tracker (line 40) | def _run_tracker(
function _child_process (line 83) | def _child_process(
function _run_child_process_and_attach (line 107) | def _run_child_process_and_attach(args: argparse.Namespace) -> None:
function _run_with_socket_output (line 145) | def _run_with_socket_output(args: argparse.Namespace) -> None:
function _run_with_file_output (line 159) | def _run_with_file_output(args: argparse.Namespace) -> None:
class RunCommand (line 197) | class RunCommand:
method prepare_parser (line 200) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
method validate_target_file (line 302) | def validate_target_file(self, args: argparse.Namespace) -> None:
method run (line 318) | def run(self, args: argparse.Namespace, parser: argparse.ArgumentParse...
FILE: src/memray/commands/stats.py
class StatsCommand (line 11) | class StatsCommand:
method prepare_parser (line 14) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
method run (line 57) | def run(self, args: argparse.Namespace, parser: argparse.ArgumentParse...
FILE: src/memray/commands/summary.py
class SummaryCommand (line 13) | class SummaryCommand:
method prepare_parser (line 16) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
method run (line 58) | def run(self, args: argparse.Namespace, parser: argparse.ArgumentParse...
FILE: src/memray/commands/table.py
class TableCommand (line 7) | class TableCommand(HighWatermarkCommand):
method __init__ (line 10) | def __init__(self) -> None:
method prepare_parser (line 16) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
FILE: src/memray/commands/transform.py
class TransformCommand (line 14) | class TransformCommand(HighWatermarkCommand):
method __init__ (line 17) | def __init__(self) -> None:
method prepare_parser (line 25) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
method run (line 33) | def run(self, args: argparse.Namespace, parser: argparse.ArgumentParse...
method post_run_gprof2dot (line 49) | def post_run_gprof2dot(self) -> None:
FILE: src/memray/commands/tree.py
class TreeCommand (line 13) | class TreeCommand:
method prepare_parser (line 16) | def prepare_parser(self, parser: argparse.ArgumentParser) -> None:
method run (line 51) | def run(self, args: argparse.Namespace, parser: argparse.ArgumentParse...
FILE: src/memray/reporters/__init__.py
class BaseReporter (line 12) | class BaseReporter(Protocol):
method render (line 13) | def render(
FILE: src/memray/reporters/_textual_hacks.py
function update_key_description (line 23) | def update_key_description(bindings: Bindings, key: str, description: st...
function redraw_footer (line 32) | def redraw_footer(app: App[Any]) -> None:
FILE: src/memray/reporters/assets/common.js
function initMemoryGraph (line 3) | function initMemoryGraph(memory_records) {
function resizeMemoryGraph (line 108) | function resizeMemoryGraph() {
function humanFileSize (line 115) | function humanFileSize(bytes, dp = 1) {
function debounced (line 132) | function debounced(fn) {
function makeTooltipString (line 149) | function makeTooltipString(data, totalSize, merge_threads) {
function filterFrames (line 171) | function filterFrames(root, compFunction) {
function filterChildThreads (line 192) | function filterChildThreads(root, threadId) {
function filterFramesByFunc (line 203) | function filterFramesByFunc(root, func) {
function filterUninteresting (line 229) | function filterUninteresting(root) {
function filterImportSystem (line 235) | function filterImportSystem(root) {
function sumAllocations (line 248) | function sumAllocations(data) {
FILE: src/memray/reporters/assets/flamegraph.js
function packedDataToTree (line 18) | function packedDataToTree(packedData) {
function initTrees (line 45) | function initTrees(packedData) {
function main (line 66) | function main() {
FILE: src/memray/reporters/assets/flamegraph_common.js
constant FILTER_UNINTERESTING (line 17) | const FILTER_UNINTERESTING = "filter_uninteresting";
constant FILTER_IMPORT_SYSTEM (line 18) | const FILTER_IMPORT_SYSTEM = "filter_import_system";
constant FILTER_THREAD (line 19) | const FILTER_THREAD = "filter_thread";
class FilteredChart (line 21) | class FilteredChart {
method constructor (line 22) | constructor() {
method registerFilter (line 25) | registerFilter(name, func) {
method unRegisterFilter (line 28) | unRegisterFilter(name) {
method drawChart (line 32) | drawChart(data) {
function getFlamegraph (line 47) | function getFlamegraph() {
function getFilteredChart (line 51) | function getFilteredChart() {
function getCurrentId (line 56) | function getCurrentId() {
function updateZoomButtom (line 64) | function updateZoomButtom() {
function onClick (line 68) | function onClick(d) {
function handleFragments (line 75) | function handleFragments() {
function onInvert (line 85) | function onInvert() {
function onResetZoom (line 93) | function onResetZoom() {
function getChartWidth (line 98) | function getChartWidth() {
function onResize (line 103) | function onResize() {
function onFilterThread (line 112) | function onFilterThread() {
function onFilterUninteresting (line 130) | function onFilterUninteresting() {
function onFilterImportSystem (line 148) | function onFilterImportSystem() {
function getTooltipDirection (line 177) | function getTooltipDirection(d) {
function toPlacement (line 196) | function toPlacement(direction) {
function getTooltip (line 210) | function getTooltip() {
function decimalHash (line 287) | function decimalHash(string) {
function fileExtension (line 294) | function fileExtension(filename) {
function colorByExtension (line 302) | function colorByExtension(extension) {
function memrayColorMapper (line 312) | function memrayColorMapper(d, originalColor) {
function initThreadsDropdown (line 326) | function initThreadsDropdown(data, merge_threads) {
function drawChart (line 347) | function drawChart(chart_data) {
FILE: src/memray/reporters/assets/table.js
function main (line 4) | function main() {
FILE: src/memray/reporters/assets/temporal_flamegraph.js
function generateParentIndexes (line 25) | function generateParentIndexes(nodes) {
function generateNodeObjects (line 35) | function generateNodeObjects(strings, nodes) {
function initTrees (line 60) | function initTrees(packedData) {
function findHWMAllocations (line 84) | function findHWMAllocations(
function findLeakedAllocations (line 106) | function findLeakedAllocations(
function packedDataToTree (line 130) | function packedDataToTree(packedData, rangeStart, rangeEnd) {
function initMemoryGraph (line 245) | function initMemoryGraph(memory_records) {
function showLoadingAnimation (line 296) | function showLoadingAnimation() {
function hideLoadingAnimation (line 302) | function hideLoadingAnimation() {
function refreshFlamegraph (line 308) | function refreshFlamegraph(event) {
function getRangeData (line 362) | function getRangeData(event) {
function refreshFlamegraphDebounced (line 388) | function refreshFlamegraphDebounced(event) {
function main (line 399) | function main() {
FILE: src/memray/reporters/common.py
function format_thread_name (line 7) | def format_thread_name(
FILE: src/memray/reporters/flamegraph.py
class RecordData (line 42) | class RecordData(TypedDict):
class FrameNodeDict (line 49) | class FrameNodeDict(TypedDict):
class FlameGraphNodeDict (line 60) | class FlameGraphNodeDict(TypedDict):
function create_framegraph_node_from_stack_frame (line 73) | def create_framegraph_node_from_stack_frame(
class StringRegistry (line 101) | class StringRegistry:
method __init__ (line 102) | def __init__(self) -> None:
method register (line 106) | def register(self, string: str) -> int:
class FlameGraphReporter (line 113) | class FlameGraphReporter:
method __init__ (line 114) | def __init__(
method generate_nodes (line 125) | def generate_nodes(
method generate_frames (line 147) | def generate_frames(
method _create_root_node (line 214) | def _create_root_node(cls) -> FrameNodeDict:
method _drop_import_system_frames (line 227) | def _drop_import_system_frames(
method _from_any_snapshot (line 241) | def _from_any_snapshot(
method from_snapshot (line 350) | def from_snapshot(
method from_temporal_snapshot (line 367) | def from_temporal_snapshot(
method render (line 386) | def render(
FILE: src/memray/reporters/frame_tools.py
function _is_cpython_internal_symbol (line 38) | def _is_cpython_internal_symbol(symbol: str, file: str) -> bool:
function is_cpython_internal (line 60) | def is_cpython_internal(frame: StackFrame) -> bool:
function is_frame_interesting (line 65) | def is_frame_interesting(frame: StackFrame) -> bool:
function is_frame_from_import_system (line 74) | def is_frame_from_import_system(frame: StackFrame) -> bool:
FILE: src/memray/reporters/stats.py
function get_histogram_databins (line 22) | def get_histogram_databins(data: Dict[int, int], bins: int) -> List[Tupl...
function describe_histogram_databins (line 41) | def describe_histogram_databins(
function draw_histogram (line 54) | def draw_histogram(
class StatsReporter (line 106) | class StatsReporter:
method __init__ (line 107) | def __init__(self, stats: Stats, num_largest: int):
method render (line 113) | def render(self, json_output_file: Optional[Path] = None) -> None:
method _render_to_terminal (line 123) | def _render_to_terminal(self, histogram_params: Dict[str, int]) -> None:
method _render_to_json (line 165) | def _render_to_json(self, histogram_params: Dict[str, int], out_path: ...
method _format_location (line 199) | def _format_location(loc: Tuple[str, str, int]) -> str:
method _get_top_allocations_by_size (line 205) | def _get_top_allocations_by_size(self) -> Iterator[Tuple[PythonStackEl...
method _get_top_allocations_by_count (line 209) | def _get_top_allocations_by_count(self) -> Iterator[Tuple[PythonStackE...
method _get_allocator_type_distribution (line 213) | def _get_allocator_type_distribution(self) -> Iterator[Tuple[str, int]]:
FILE: src/memray/reporters/summary.py
function _get_terminal_lines (line 19) | def _get_terminal_lines() -> int:
function _size_to_color (line 26) | def _size_to_color(proportion_of_total: float) -> str:
class SummaryReporter (line 37) | class SummaryReporter:
method __init__ (line 48) | def __init__(self, data: Iterable[AllocationRecord], native: bool):
method from_snapshot (line 59) | def from_snapshot(
method render (line 64) | def render(
FILE: src/memray/reporters/table.py
class TableReporter (line 16) | class TableReporter:
method __init__ (line 17) | def __init__(
method from_snapshot (line 28) | def from_snapshot(
method render (line 61) | def render(
FILE: src/memray/reporters/templates/__init__.py
function get_render_environment (line 16) | def get_render_environment() -> jinja2.Environment:
function get_report_title (line 31) | def get_report_title(
function render_report (line 44) | def render_report(
FILE: src/memray/reporters/templates/assets/flamegraph.js
method 543 (line 1) | 543(t,n,e){var r;
method 224 (line 9) | 224(t,n,e){"use strict";e.d(n,{Hw:()=>p,Kc:()=>o,P2:()=>v,Qx:()=>l,bn:()...
method 279 (line 9) | 279(t,n,e){"use strict";e.d(n,{$d:()=>Gt,QA:()=>Ct,kj:()=>Wt,zb:()=>Zt,Y...
function e (line 9) | function e(r){var i=n[r];if(void 0!==i)return i.exports;var o=n[r]={id:r...
function r (line 9) | function r(t){const{strings:n,nodes:e,unique_threads:r}=t,i=e.name.map((...
FILE: src/memray/reporters/templates/assets/flamegraph_common.js
method 543 (line 1) | 543(t,n,r){var e;
method 224 (line 9) | 224(t,n,r){"use strict";r.d(n,{bn:()=>e,ni:()=>i});r(543);function e(t,n...
function r (line 9) | function r(e){var i=n[e];if(void 0!==i)return i.exports;var u=n[e]={id:e...
function c (line 9) | function c(t,r,i){return e(t,n(r,i))}
function l (line 9) | function l(t,n){return"function"==typeof t?t(n):t}
function s (line 9) | function s(t){return t.split("-")[0]}
function h (line 9) | function h(t){return t.split("-")[1]}
function p (line 9) | function p(t){return"x"===t?"y":"x"}
function v (line 9) | function v(t){return"y"===t?"height":"width"}
function d (line 9) | function d(t){return g.has(s(t))?"y":"x"}
function y (line 9) | function y(t){return p(d(t))}
function m (line 9) | function m(t){return t.replace(/start|end/g,t=>f[t])}
function R (line 9) | function R(t,n,r,e){const i=h(t);let u=function(t,n,r){switch(t){case"to...
function j (line 9) | function j(t){return t.replace(/left|right|bottom|top/g,t=>a[t])}
function E (line 9) | function E(t){const{x:n,y:r,width:e,height:i}=t;return{width:e,height:i,...
function O (line 9) | function O(t,n,r){let{reference:e,floating:i}=t;const u=d(n),o=y(n),a=v(...
function S (line 9) | async function S(t,n){var r;void 0===n&&(n={});const{x:e,y:i,platform:u,...
function L (line 9) | function L(){return"undefined"!=typeof window}
function T (line 9) | function T(t){return z(t)?(t.nodeName||"").toLowerCase():"#document"}
function I (line 9) | function I(t){var n;return(null==t||null==(n=t.ownerDocument)?void 0:n.d...
function C (line 9) | function C(t){var n;return null==(n=(z(t)?t.ownerDocument:t.document)||w...
function z (line 9) | function z(t){return!!L()&&(t instanceof Node||t instanceof I(t).Node)}
function B (line 9) | function B(t){return!!L()&&(t instanceof Element||t instanceof I(t).Elem...
function W (line 9) | function W(t){return!!L()&&(t instanceof HTMLElement||t instanceof I(t)....
function D (line 9) | function D(t){return!(!L()||"undefined"==typeof ShadowRoot)&&(t instance...
function $ (line 9) | function $(t){const{overflow:n,overflowX:r,overflowY:e,display:i}=J(t);r...
function M (line 9) | function M(t){return P.has(T(t))}
function N (line 9) | function N(t){return U.some(n=>{try{return t.matches(n)}catch(t){return!...
function Z (line 9) | function Z(t){const n=K(),r=B(t)?J(t):t;return q.some(t=>!!r[t]&&"none"!...
function K (line 9) | function K(){return!("undefined"==typeof CSS||!CSS.supports)&&CSS.suppor...
function Y (line 9) | function Y(t){return G.has(T(t))}
function J (line 9) | function J(t){return I(t).getComputedStyle(t)}
function X (line 9) | function X(t){return B(t)?{scrollLeft:t.scrollLeft,scrollTop:t.scrollTop...
function Q (line 9) | function Q(t){if("html"===T(t))return t;const n=t.assignedSlot||t.parent...
function tt (line 9) | function tt(t){const n=Q(t);return Y(n)?t.ownerDocument?t.ownerDocument....
function nt (line 9) | function nt(t,n,r){var e;void 0===n&&(n=[]),void 0===r&&(r=!0);const i=t...
function rt (line 9) | function rt(t){return t.parent&&Object.getPrototypeOf(t.parent)?t.frameE...
function et (line 9) | function et(t){const n=J(t);let r=parseFloat(n.width)||0,e=parseFloat(n....
function it (line 9) | function it(t){return B(t)?t:t.contextElement}
function ut (line 9) | function ut(t){const n=it(t);if(!W(n))return o(1);const r=n.getBoundingC...
function at (line 9) | function at(t){const n=I(t);return K()&&n.visualViewport?{x:n.visualView...
function ft (line 9) | function ft(t,n,r,e){void 0===n&&(n=!1),void 0===r&&(r=!1);const i=t.get...
function ct (line 9) | function ct(t,n){const r=X(t).scrollLeft;return n?n.left+r:ft(C(t)).left+r}
function lt (line 9) | function lt(t,n){const r=t.getBoundingClientRect();return{x:r.left+n.scr...
function ht (line 9) | function ht(t,n,r){let i;if("viewport"===n)i=function(t,n){const r=I(t),...
function pt (line 9) | function pt(t,n){const r=Q(t);return!(r===n||!B(r)||Y(r))&&("fixed"===J(...
function vt (line 9) | function vt(t,n,r){const e=W(n),i=C(n),u="fixed"===r,a=ft(t,!0,u,n);let ...
function gt (line 9) | function gt(t){return"static"===J(t).position}
function dt (line 9) | function dt(t,n){if(!W(t)||"fixed"===J(t).position)return null;if(n)retu...
function _t (line 9) | function _t(t,n){const r=I(t);if(N(t))return r;if(!W(t)){let n=Q(t);for(...
function mt (line 9) | function mt(t,n){return t.x===n.x&&t.y===n.y&&t.width===n.width&&t.heigh...
function wt (line 9) | function wt(t,r,i,o){void 0===o&&(o={});const{ancestorScroll:a=!0,ancest...
method fn (line 9) | async fn(n){var r,e;const{x:i,y:u,placement:o,middlewareData:a}=n,f=awai...
method fn (line 9) | async fn(n){const{x:r,y:e,placement:i,platform:u}=n,{mainAxis:o=!0,cross...
method fn (line 9) | async fn(n){var r,e;const{placement:i,middlewareData:u,rects:o,initialPl...
method constructor (line 9) | constructor(){this.filters={}}
method registerFilter (line 9) | registerFilter(t,n){this.filters[t]=n}
method unRegisterFilter (line 9) | unRegisterFilter(t){delete this.filters[t]}
method drawChart (line 9) | drawChart(n){let r=n;_.forOwn(this.filters,t=>{r=t(r)}),function(n){let ...
function Ot (line 9) | function Ot(){return location.hash?parseInt(location.hash.substring(1),1...
function St (line 9) | function St(){document.getElementById("resetZoomButton").disabled=0==Ot()}
function kt (line 9) | function kt(t){t.id!=Ot()&&(history.pushState({id:t.id},t.data.name,`#${...
function Lt (line 9) | function Lt(){return document.getElementById("chart").clientWidth}
function Tt (line 9) | function Tt(t,n){return t.highlight?"orange":t.data.name&&t.data.locatio...
FILE: src/memray/reporters/templates/assets/table.js
method 543 (line 1) | 543(n,t,r){var e;
function r (line 9) | function r(e){var u=t[e];if(void 0!==u)return u.exports;var i=t[e]={id:e...
function n (line 9) | function n(){setTimeout(()=>{Plotly.Plots.resize("memoryGraph"),Plotly.P...
FILE: src/memray/reporters/templates/assets/temporal_flamegraph.js
method 543 (line 1) | 543(t,n,e){var r;
method 224 (line 9) | 224(t,n,e){"use strict";e.d(n,{Hw:()=>s,P2:()=>h,Qx:()=>c,bn:()=>o,kO:()...
method 279 (line 9) | 279(t,n,e){"use strict";e.d(n,{Iv:()=>Ct,QA:()=>Dt,kj:()=>Pt,zb:()=>Kt,Y...
function e (line 9) | function e(r){var i=n[r];if(void 0!==i)return i.exports;var o=n[r]={id:r...
function a (line 9) | function a(t){let n=new Array(t.children.length);console.log("finding pa...
function c (line 9) | function c(t,n){console.log("constructing nodes");const e=n.name.map((e,...
function l (line 9) | function l(t,n,e,r){t.forEach(t=>{let[i,o,u,a,c]=t;if(i<=e&&(null===o||o...
function f (line 9) | function f(t,n,e,r,i){t.forEach(t=>{let[o,u,a,c,l]=t;if(o>=e&&o<=r&&(nul...
function s (line 9) | function s(t,n,e){const{flamegraphNodeObjects:r,invertedNoImportsNodeObj...
function h (line 9) | function h(t){console.log("refreshing flame graph!");let e=function(t){c...
function d (line 9) | function d(t){console.log("refreshFlamegraphDebounced"),p&&clearTimeout(...
FILE: src/memray/reporters/transform.py
class TransformReporter (line 19) | class TransformReporter:
method __init__ (line 25) | def __init__(
method render_as_gprof2dot (line 40) | def render_as_gprof2dot(
method render (line 76) | def render(
method render_as_csv (line 94) | def render_as_csv(
FILE: src/memray/reporters/tree.py
class Frame (line 57) | class Frame:
class ElidedLocations (line 70) | class ElidedLocations:
class FrameDetailScreen (line 79) | class FrameDetailScreen(Widget):
method __init__ (line 84) | def __init__(
method on_mount (line 91) | def on_mount(self) -> None:
method update_text_area (line 95) | async def update_text_area(self) -> None:
method _get_content_by_label_id (line 115) | def _get_content_by_label_id(self) -> Dict[str, str]:
method watch_frame (line 158) | def watch_frame(self) -> None:
method compose (line 171) | def compose(self) -> ComposeResult:
class FrameTree (line 210) | class FrameTree(Tree[Frame]):
method on_tree_node_selected (line 211) | def on_tree_node_selected(self, node: Tree.NodeSelected[Frame]) -> None:
method on_tree_node_highlighted (line 215) | def on_tree_node_highlighted(self, node: Tree.NodeHighlighted[Frame]) ...
function node_is_interesting (line 220) | def node_is_interesting(node: Frame) -> bool:
function node_is_not_import_system (line 224) | def node_is_not_import_system(node: Frame) -> bool:
class TreeScreen (line 228) | class TreeScreen(Screen[None]):
method __init__ (line 245) | def __init__(
method expand_first_child (line 258) | def expand_first_child(self, node: TreeNode[Frame]) -> None:
method compose (line 263) | def compose(self) -> ComposeResult:
method repopulate_tree (line 275) | def repopulate_tree(self, tree: FrameTree) -> None:
method action_expand_linear_group (line 285) | def action_expand_linear_group(self) -> None:
method frame_text (line 294) | def frame_text(self, node: Frame, *, allow_expand: bool) -> Text:
method add_children (line 320) | def add_children(self, tree: TreeNode[Frame], children: Iterable[Frame...
method add_elided_locations_node (line 343) | def add_elided_locations_node(self, tree: TreeNode[Frame]) -> None:
method action_toggle_import_system (line 366) | def action_toggle_import_system(self) -> None:
method action_toggle_uninteresting (line 375) | def action_toggle_uninteresting(self) -> None:
method rewrite_bindings (line 384) | def rewrite_bindings(self, bindings: Bindings) -> None:
method active_bindings (line 391) | def active_bindings(self) -> Dict[str, "binding.ActiveBinding"]:
class TreeApp (line 397) | class TreeApp(App[None]):
method __init__ (line 398) | def __init__(
method on_mount (line 406) | def on_mount(self) -> None:
method namespace_bindings (line 412) | def namespace_bindings(self) -> Dict[str, Tuple[DOMNode, Binding]]:
function _percentage_to_color (line 419) | def _percentage_to_color(percentage: int) -> Color:
function _info_color (line 429) | def _info_color(node: Frame, root_node: Frame) -> Color:
class TreeReporter (line 434) | class TreeReporter:
method __init__ (line 435) | def __init__(self, data: Frame, elided_locations: ElidedLocations) -> ...
method from_snapshot (line 441) | def from_snapshot(
method get_app (line 497) | def get_app(self) -> TreeApp:
method render (line 500) | def render(
FILE: src/memray/reporters/tui.py
class Location (line 58) | class Location:
class AllocationEntry (line 64) | class AllocationEntry:
class Snapshot (line 72) | class Snapshot:
class SnapshotFetched (line 81) | class SnapshotFetched(Message):
method __init__ (line 82) | def __init__(self, snapshot: Snapshot, disconnected: bool) -> None:
class MemoryGraph (line 88) | class MemoryGraph(Widget):
method __init__ (line 89) | def __init__(
method _value_to_blocks (line 114) | def _value_to_blocks(self, value: float) -> List[int]:
method add_value (line 133) | def add_value(self, value: float) -> None:
method render_line (line 145) | def render_line(self, y: int) -> Strip:
class SortableText (line 164) | class SortableText(Text):
method __init__ (line 167) | def __init__(
method __lt__ (line 181) | def __lt__(self, other: Any) -> bool:
method __gt__ (line 186) | def __gt__(self, other: Any) -> bool:
method __eq__ (line 191) | def __eq__(self, other: Any) -> bool:
function aggregate_allocations (line 197) | def aggregate_allocations(
class TimeDisplay (line 247) | class TimeDisplay(Static):
method on_mount (line 250) | def on_mount(self) -> None:
function _filename_to_module_name (line 255) | def _filename_to_module_name(file: str) -> str:
class AllocationTable (line 268) | class AllocationTable(Widget):
method __init__ (line 319) | def __init__(self) -> None:
method _get_color (line 331) | def _get_color(self, value: float, max: float) -> Color:
method get_heading (line 334) | def get_heading(self, column_idx: int) -> Text:
method compose (line 357) | def compose(self) -> ComposeResult:
method watch_current_thread (line 371) | def watch_current_thread(self) -> None:
method watch_merge_threads (line 375) | def watch_merge_threads(self) -> None:
method watch_snapshot (line 379) | def watch_snapshot(self) -> None:
method watch_sort_column_id (line 383) | def watch_sort_column_id(self, sort_column_id: int) -> None:
method populate_table (line 392) | def populate_table(self) -> None:
class Header (line 466) | class Header(Widget):
method __init__ (line 475) | def __init__(self, pid: Optional[int], cmd_line: Optional[str]):
method compose (line 482) | def compose(self) -> ComposeResult:
method watch_n_samples (line 503) | def watch_n_samples(self, n_samples: int) -> None:
method watch_last_update (line 507) | def watch_last_update(self, last_update: datetime) -> None:
class TUI (line 514) | class TUI(Screen[None]):
method __init__ (line 544) | def __init__(self, pid: Optional[int], cmd_line: Optional[str], native...
method current_thread (line 554) | def current_thread(self) -> int:
method action_previous_thread (line 557) | def action_previous_thread(self) -> None:
method action_next_thread (line 562) | def action_next_thread(self) -> None:
method action_sort (line 567) | def action_sort(self, col_number: int) -> None:
method _populate_header_thread_labels (line 571) | def _populate_header_thread_labels(self, thread_idx: int) -> None:
method action_toggle_merge_threads (line 585) | def action_toggle_merge_threads(self) -> None:
method action_toggle_pause (line 592) | def action_toggle_pause(self) -> None:
method action_scroll_grid (line 600) | def action_scroll_grid(self, direction: str) -> None:
method watch_thread_idx (line 605) | def watch_thread_idx(self, thread_idx: int) -> None:
method watch_threads (line 610) | def watch_threads(self) -> None:
method watch_disconnected (line 614) | def watch_disconnected(self) -> None:
method watch_paused (line 618) | def watch_paused(self) -> None:
method watch_snapshot (line 621) | def watch_snapshot(self, snapshot: Snapshot) -> None:
method update_label (line 626) | def update_label(self) -> None:
method compose (line 638) | def compose(self) -> ComposeResult:
method display_snapshot (line 648) | def display_snapshot(self) -> None:
method update_sort_key (line 684) | def update_sort_key(self, col_number: int) -> None:
method rewrite_bindings (line 689) | def rewrite_bindings(self, bindings: Bindings) -> None:
method active_bindings (line 702) | def active_bindings(self) -> Dict[str, Any]:
class UpdateThread (line 708) | class UpdateThread(threading.Thread):
method __init__ (line 709) | def __init__(self, app: "TUIApp", reader: SocketReader) -> None:
method run (line 717) | def run(self) -> None:
method cancel (line 744) | def cancel(self) -> None:
method schedule_update (line 748) | def schedule_update(self) -> None:
class TUIApp (line 752) | class TUIApp(App[None]):
method __init__ (line 757) | def __init__(
method on_mount (line 770) | def on_mount(self) -> None:
method on_unmount (line 792) | def on_unmount(self) -> None:
method on_snapshot_fetched (line 797) | def on_snapshot_fetched(self, message: SnapshotFetched) -> None:
method on_resize (line 805) | def on_resize(self, event: events.Resize) -> None:
method namespace_bindings (line 811) | def namespace_bindings(self) -> Dict[str, Tuple[DOMNode, Binding]]:
FILE: src/vendor/libbacktrace/alloc.c
type backtrace_state (line 51) | struct backtrace_state
function backtrace_free (line 68) | void
type backtrace_state (line 80) | struct backtrace_state
type backtrace_vector (line 82) | struct backtrace_vector
type backtrace_state (line 121) | struct backtrace_state
type backtrace_vector (line 122) | struct backtrace_vector
function backtrace_vector_release (line 142) | int
FILE: src/vendor/libbacktrace/allocfail.c
function error_callback_full (line 55) | static void
function callback_full (line 69) | static int
function test1 (line 79) | static int
function f2 (line 85) | static int
function f3 (line 91) | static int
function main (line 112) | int
FILE: src/vendor/libbacktrace/atomic.c
function backtrace_atomic_load_int (line 64) | int
function backtrace_atomic_store_pointer (line 77) | void
function backtrace_atomic_store_size_t (line 91) | void
function backtrace_atomic_store_int (line 103) | void
FILE: src/vendor/libbacktrace/backtrace.c
type backtrace_data (line 45) | struct backtrace_data
function _Unwind_Reason_Code (line 66) | static _Unwind_Reason_Code
function backtrace_full (line 101) | int __attribute__((noinline))
FILE: src/vendor/libbacktrace/backtrace.h
type backtrace_state (line 47) | struct backtrace_state
type backtrace_state (line 87) | struct backtrace_state
type backtrace_state (line 114) | struct backtrace_state
type backtrace_state (line 133) | struct backtrace_state
type backtrace_state (line 143) | struct backtrace_state
type backtrace_state (line 154) | struct backtrace_state
type backtrace_state (line 180) | struct backtrace_state
FILE: src/vendor/libbacktrace/btest.c
function test1 (line 56) | static int
function f2 (line 64) | static int
function f3 (line 70) | static int
function test2 (line 118) | static inline int
function f12 (line 124) | static inline int
function f13 (line 130) | static inline int
function test3 (line 170) | static int
function f22 (line 176) | static int
function f23 (line 182) | static int
function test4 (line 320) | static inline int
function f32 (line 326) | static inline int
function f33 (line 332) | static inline int
function test5 (line 395) | static int
function check_available_files (line 469) | static void
function check_open_files (line 479) | static void
function main (line 496) | int
FILE: src/vendor/libbacktrace/debuginfod_support.h
type debuginfod_client (line 44) | typedef struct debuginfod_client debuginfod_client;
FILE: src/vendor/libbacktrace/dwarf.c
type dwarf_tag (line 47) | enum dwarf_tag {
type dwarf_form (line 55) | enum dwarf_form {
type dwarf_attribute (line 105) | enum dwarf_attribute {
type dwarf_line_number_op (line 325) | enum dwarf_line_number_op {
type dwarf_extended_line_number_op (line 341) | enum dwarf_extended_line_number_op {
type dwarf_line_number_content_type (line 348) | enum dwarf_line_number_content_type {
type dwarf_range_list_entry (line 358) | enum dwarf_range_list_entry {
type dwarf_unit_type (line 369) | enum dwarf_unit_type {
function xstrnlen (line 384) | static size_t
type dwarf_buf (line 401) | struct dwarf_buf
type attr (line 423) | struct attr
type abbrev (line 435) | struct abbrev
type abbrevs (line 456) | struct abbrevs
type attr_val_encoding (line 466) | enum attr_val_encoding
type attr_val (line 503) | struct attr_val
type line_header (line 521) | struct line_header
type line_header_format (line 551) | struct line_header_format
type line (line 562) | struct line
type line_vector (line 580) | struct line_vector
type function (line 590) | struct function
type function_addrs (line 608) | struct function_addrs
type function_vector (line 619) | struct function_vector
type unit (line 630) | struct unit
type unit_addrs (line 690) | struct unit_addrs
type unit_addrs_vector (line 701) | struct unit_addrs_vector
type unit_vector (line 711) | struct unit_vector
type dwarf_data (line 719) | struct dwarf_data
function dwarf_buf_error (line 746) | static void
function require (line 759) | static int
function advance (line 777) | static int
type dwarf_buf (line 790) | struct dwarf_buf
function read_byte (line 808) | static unsigned char
function read_sbyte (line 820) | static signed char
function read_uint16 (line 832) | static uint16_t
function read_uint24 (line 847) | static uint32_t
function read_uint32 (line 864) | static uint32_t
function read_uint64 (line 881) | static uint64_t
function read_offset (line 903) | static uint64_t
function read_address (line 915) | static uint64_t
function is_highest_address (line 937) | static int
function read_uleb128 (line 957) | static uint64_t
function read_sleb128 (line 992) | static int64_t
function leb128_len (line 1030) | static size_t
function read_initial_length (line 1046) | static uint64_t
function free_abbrevs (line 1065) | static void
function read_attribute (line 1087) | static int
function resolve_string (line 1371) | static int
function resolve_addr_index (line 1426) | static int
function units_search (line 1458) | static int
type unit (line 1476) | struct unit
type unit (line 1477) | struct unit
type unit (line 1479) | struct unit
type unit (line 1480) | struct unit
function function_addrs_compare (line 1487) | static int
function function_addrs_search (line 1510) | static int
function add_unit_addr (line 1529) | static int
function unit_addrs_compare (line 1570) | static int
function unit_addrs_search (line 1597) | static int
function line_compare (line 1618) | static int
function line_search (line 1641) | static int
function abbrev_compare (line 1660) | static int
function read_abbrevs (line 1682) | static int
type abbrev (line 1834) | struct abbrev
type abbrevs (line 1835) | struct abbrevs
type abbrev (line 1838) | struct abbrev
type abbrev (line 1851) | struct abbrev
type abbrev (line 1857) | struct abbrev
type pcrange (line 1866) | struct pcrange {
function update_pcrange (line 1881) | static void
function add_low_high_range (line 1944) | static int
function add_ranges_from_ranges (line 1993) | static int
function add_ranges_from_rnglists (line 2061) | static int
function add_ranges (line 2241) | static int
function find_address_ranges (line 2279) | static int
function build_address_map (line 2435) | static int
function add_line (line 2631) | static int
function free_line_header (line 2669) | static void
function read_v2_paths (line 2684) | static int
function read_lnct (line 2817) | static int
function read_line_header_format_entries (line 2903) | static int
function read_line_header (line 2986) | static int
function read_line_program (line 3068) | static int
function read_line_info (line 3270) | static int
type dwarf_data (line 3353) | struct dwarf_data
type unit (line 3353) | struct unit
type dwarf_data (line 3360) | struct dwarf_data
type unit (line 3360) | struct unit
type attr (line 3361) | struct attr
type attr_val (line 3361) | struct attr_val
type unit (line 3379) | struct unit
type unit (line 3395) | struct unit
type dwarf_data (line 3414) | struct dwarf_data
type unit (line 3414) | struct unit
type dwarf_buf (line 3418) | struct dwarf_buf
type abbrev (line 3420) | struct abbrev
type attr_val (line 3464) | struct attr_val
function add_function_range (line 3525) | static int
function read_function_entry (line 3565) | static int
function read_function_info (line 3818) | static void
function report_inlined_functions (line 3904) | static int
function dwarf_lookup_pc (line 3982) | static int
function dwarf_fileline (line 4244) | static int
type dwarf_data (line 4293) | struct dwarf_data
type backtrace_state (line 4294) | struct backtrace_state
type libbacktrace_base_address (line 4295) | struct libbacktrace_base_address
type dwarf_sections (line 4296) | struct dwarf_sections
type dwarf_data (line 4298) | struct dwarf_data
type unit_addrs_vector (line 4302) | struct unit_addrs_vector
type unit_addrs (line 4303) | struct unit_addrs
type unit_vector (line 4305) | struct unit_vector
type unit (line 4306) | struct unit
type dwarf_data (line 4308) | struct dwarf_data
type unit_addrs (line 4319) | struct unit_addrs
type unit (line 4320) | struct unit
type unit_addrs (line 4323) | struct unit_addrs
type dwarf_data (line 4327) | struct dwarf_data
type dwarf_data (line 4328) | struct dwarf_data
function backtrace_dwarf_add (line 4351) | int
FILE: src/vendor/libbacktrace/edtest.c
function test1 (line 50) | static int
function f3 (line 58) | int
function main (line 100) | int
FILE: src/vendor/libbacktrace/edtest2.c
function f2 (line 38) | int f2(int x)
FILE: src/vendor/libbacktrace/elf.c
function xstrnlen (line 77) | static size_t
function xlstat (line 96) | static int
function xreadlink (line 110) | static ssize_t
type dl_phdr_info (line 128) | struct dl_phdr_info
function dl_iterate_phdr (line 134) | static int
type b_elf_half (line 193) | typedef uint16_t b_elf_half;
type b_elf_word (line 194) | typedef uint32_t b_elf_word;
type b_elf_sword (line 195) | typedef int32_t b_elf_sword;
type b_elf_addr (line 199) | typedef uint32_t b_elf_addr;
type b_elf_off (line 200) | typedef uint32_t b_elf_off;
type b_elf_wxword (line 202) | typedef uint32_t b_elf_wxword;
type b_elf_addr (line 206) | typedef uint64_t b_elf_addr;
type b_elf_off (line 207) | typedef uint64_t b_elf_off;
type b_elf_xword (line 208) | typedef uint64_t b_elf_xword;
type b_elf_sxword (line 209) | typedef int64_t b_elf_sxword;
type b_elf_wxword (line 211) | typedef uint64_t b_elf_wxword;
type b_elf_ehdr (line 219) | typedef struct {
type b_elf_shdr (line 262) | typedef struct {
type b_elf_sym (line 288) | typedef struct
type b_elf_sym (line 300) | typedef struct
type b_elf_note (line 315) | typedef struct
type b_elf_chdr (line 327) | typedef struct
type b_elf_chdr (line 336) | typedef struct
type debug_section_info (line 366) | struct debug_section_info
type elf_symbol (line 380) | struct elf_symbol
type elf_syminfo_data (line 392) | struct elf_syminfo_data
type elf_view (line 404) | struct elf_view
type elf_ppc64_opd_data (line 412) | struct elf_ppc64_opd_data
function elf_get_view (line 426) | static int
function elf_release_view (line 455) | static void
function elf_crc32 (line 466) | static uint32_t
function elf_crc32_file (line 534) | static uint32_t
function elf_nosyms (line 562) | void
function elf_nodebug (line 573) | static int
function elf_symbol_compare (line 600) | static int
function elf_symbol_search (line 618) | static int
function elf_initialize_syminfo (line 636) | int
function elf_add_syminfo_data (line 722) | static void
function elf_syminfo (line 764) | void
function elf_is_symlink (line 815) | static int
type backtrace_state (line 830) | struct backtrace_state
function elf_open_debugfile_by_debuginfod (line 866) | static int
function elf_open_debugfile_by_buildid (line 903) | static int
function elf_try_debugfile (line 959) | static int
function elf_find_debugfile_by_debuglink (line 992) | static int
function elf_open_debugfile_by_debuglink (line 1108) | static int
function elf_uncompress_failed (line 1142) | static void
function elf_fetch_bits (line 1153) | static int
function elf_fetch_bits_backward (line 1204) | static int
function elf_fetch_backward_init (line 1259) | static int
function elf_zlib_inflate_table (line 1380) | static int
function main (line 1700) | int
function elf_zlib_inflate (line 1853) | static int
function elf_zlib_verify_checksum (line 2554) | static int
function elf_zlib_inflate_and_verify (line 2680) | static int
type elf_zstd_fse_entry (line 2726) | struct elf_zstd_fse_entry
type elf_zstd_fse_entry (line 2738) | struct elf_zstd_fse_entry
function elf_zstd_read_fse (line 2748) | static int
function elf_zstd_build_fse (line 2934) | static int
type elf_zstd_fse_baseline_entry (line 3088) | struct elf_zstd_fse_baseline_entry
function elf_zstd_make_literal_baseline_fse (line 3103) | static int
function elf_zstd_make_offset_baseline_fse (line 3159) | static int
function elf_zstd_make_match_baseline_fse (line 3222) | static int
function print_table (line 3306) | static void
function main (line 3326) | int
type elf_zstd_fse_baseline_entry (line 3401) | struct elf_zstd_fse_baseline_entry
type elf_zstd_fse_baseline_entry (line 3427) | struct elf_zstd_fse_baseline_entry
type elf_zstd_fse_baseline_entry (line 3453) | struct elf_zstd_fse_baseline_entry
function elf_zstd_read_huff (line 3474) | static int
function elf_zstd_read_literals (line 3765) | static int
type elf_zstd_seq_decode (line 4288) | struct elf_zstd_seq_decode
function elf_zstd_unpack_seq_decode (line 4296) | static int
function elf_zstd_decompress (line 4373) | static int
function elf_uncompress_zdebug (line 5048) | static int
function elf_uncompress_chdr (line 5101) | static int
function backtrace_uncompress_zdebug (line 5174) | int
function backtrace_uncompress_zstd (line 5200) | int
function elf_lzma_varint (line 5390) | static int
function elf_lzma_range_normalize (line 5430) | static void
function elf_lzma_bit (line 5453) | static int
function elf_lzma_integer (line 5481) | static uint32_t
function elf_lzma_reverse_integer (line 5505) | static uint32_t
function elf_lzma_len (line 5533) | static uint32_t
function elf_uncompress_lzma_block (line 5590) | static int
function elf_uncompress_lzma (line 6285) | static int
function backtrace_uncompress_lzma (line 6516) | int
function elf_add (line 6535) | int
type phdr_data (line 7371) | struct phdr_data
type dl_phdr_info (line 7390) | struct dl_phdr_info
type phdr_data (line 7393) | struct phdr_data
type libbacktrace_base_address (line 7397) | struct libbacktrace_base_address
function backtrace_initialize (line 7446) | int
FILE: src/vendor/libbacktrace/fileline.c
type backtrace_state (line 77) | struct backtrace_state
type backtrace_state (line 108) | struct backtrace_state
type backtrace_state (line 125) | struct backtrace_state
type backtrace_state (line 144) | struct backtrace_state
function fileline_initialize (line 214) | static int
function backtrace_pcinfo (line 351) | int
function backtrace_syminfo (line 367) | int
function backtrace_syminfo_to_full_callback (line 386) | void
function backtrace_syminfo_to_full_error_callback (line 400) | void
FILE: src/vendor/libbacktrace/instrumented_alloc.c
function at_fail_alloc_p (line 98) | int
function get_nr_allocs (line 104) | uint64_t
function set_fail_at_alloc (line 110) | void
FILE: src/vendor/libbacktrace/internal.h
type backtrace_state (line 131) | struct backtrace_state
type backtrace_state (line 138) | struct backtrace_state
type backtrace_state (line 144) | struct backtrace_state
type backtrace_view (line 186) | struct backtrace_view
type backtrace_state (line 198) | struct backtrace_state
type backtrace_view (line 201) | struct backtrace_view
type backtrace_state (line 204) | struct backtrace_state
type backtrace_view (line 205) | struct backtrace_view
type backtrace_state (line 224) | struct backtrace_state
type backtrace_state (line 231) | struct backtrace_state
type backtrace_vector (line 240) | struct backtrace_vector
type backtrace_state (line 254) | struct backtrace_state
type backtrace_vector (line 257) | struct backtrace_vector
type backtrace_state (line 264) | struct backtrace_state
type backtrace_vector (line 265) | struct backtrace_vector
type backtrace_state (line 272) | struct backtrace_state
type backtrace_vector (line 273) | struct backtrace_vector
function backtrace_vector_free (line 279) | static inline void
type backtrace_state (line 299) | struct backtrace_state
type dwarf_section (line 308) | enum dwarf_section
type dwarf_sections (line 325) | struct dwarf_sections
type dwarf_data (line 333) | struct dwarf_data
type libbacktrace_base_address (line 348) | struct libbacktrace_base_address
type libbacktrace_base_address (line 360) | struct libbacktrace_base_address
type backtrace_state (line 371) | struct backtrace_state
type libbacktrace_base_address (line 372) | struct libbacktrace_base_address
type dwarf_sections (line 373) | struct dwarf_sections
type dwarf_data (line 375) | struct dwarf_data
type dwarf_data (line 378) | struct dwarf_data
type backtrace_call_full (line 382) | struct backtrace_call_full
type backtrace_state (line 407) | struct backtrace_state
type backtrace_state (line 416) | struct backtrace_state
type backtrace_state (line 425) | struct backtrace_state
type elf_ppc64_opd_data (line 432) | struct elf_ppc64_opd_data
type backtrace_state (line 433) | struct backtrace_state
type libbacktrace_base_address (line 435) | struct libbacktrace_base_address
type elf_ppc64_opd_data (line 436) | struct elf_ppc64_opd_data
type dwarf_data (line 439) | struct dwarf_data
type backtrace_state (line 441) | struct backtrace_state
type backtrace_state (line 445) | struct backtrace_state
type backtrace_state (line 450) | struct backtrace_state
type libbacktrace_base_address (line 452) | struct libbacktrace_base_address
type backtrace_state (line 455) | struct backtrace_state
type backtrace_state (line 459) | struct backtrace_state
FILE: src/vendor/libbacktrace/macho.c
type macho_header_32 (line 49) | struct macho_header_32
type macho_header_64 (line 62) | struct macho_header_64
type macho_header_fat (line 76) | struct macho_header_fat
type macho_fat_arch (line 102) | struct macho_fat_arch
type macho_fat_arch_64 (line 115) | struct macho_fat_arch_64
type macho_load_command (line 140) | struct macho_load_command
type macho_segment_command (line 159) | struct macho_segment_command
type macho_segment_64_command (line 176) | struct macho_segment_64_command
type macho_symtab_command (line 193) | struct macho_symtab_command
type macho_uuid_command (line 209) | struct macho_uuid_command
type macho_section (line 218) | struct macho_section
type macho_section_64 (line 235) | struct macho_section_64
type macho_nlist (line 253) | struct macho_nlist
type macho_nlist_64 (line 264) | struct macho_nlist_64
type macho_symbol (line 289) | struct macho_symbol
type macho_syminfo_data (line 297) | struct macho_syminfo_data
function macho_nodebug (line 321) | static int
function macho_nosyms (line 334) | void
function macho_add_dwarf_section (line 346) | static int
function macho_add_dwarf_segment (line 379) | static int
function macho_symbol_compare (line 447) | static int
function macho_symbol_search (line 465) | static int
function macho_defined_symbol (line 490) | static int
function macho_add_symtab (line 519) | static int
function macho_syminfo (line 712) | void
function macho_add_fat (line 765) | static int
function macho_add_dsym (line 869) | static int
function macho_add (line 987) | int
function backtrace_initialize (line 1235) | int
function backtrace_initialize (line 1326) | int
FILE: src/vendor/libbacktrace/mmap.c
type backtrace_freelist_struct (line 63) | struct backtrace_freelist_struct
function backtrace_free_locked (line 73) | static void
type backtrace_state (line 114) | struct backtrace_state
type backtrace_freelist_struct (line 120) | struct backtrace_freelist_struct
type backtrace_freelist_struct (line 143) | struct backtrace_freelist_struct
function backtrace_free (line 194) | void
type backtrace_state (line 243) | struct backtrace_state
type backtrace_vector (line 245) | struct backtrace_vector
type backtrace_state (line 293) | struct backtrace_state
type backtrace_vector (line 294) | struct backtrace_vector
function backtrace_vector_release (line 308) | int
FILE: src/vendor/libbacktrace/mmapio.c
function backtrace_get_view (line 56) | int
function backtrace_release_view (line 96) | void
FILE: src/vendor/libbacktrace/mtest.c
function callback_mtest (line 61) | static int
function test1 (line 83) | static int
function f2 (line 91) | static int
function f3 (line 97) | static int
function test3 (line 218) | static int
function f22 (line 224) | static int
function f23 (line 230) | static int
function test5 (line 328) | int
function main (line 395) | int
FILE: src/vendor/libbacktrace/nounwind.c
function backtrace_full (line 44) | int
function backtrace_simple (line 56) | int
FILE: src/vendor/libbacktrace/pecoff.c
type dll_notification_data (line 73) | struct dll_notification_data
type LONG (line 85) | typedef LONG NTSTATUS;
type VOID (line 86) | typedef VOID CALLBACK (*LDR_DLL_NOTIFICATION)(ULONG,
type NTSTATUS (line 89) | typedef NTSTATUS NTAPI (*LDR_REGISTER_FUNCTION)(ULONG,
type b_coff_file_header (line 96) | typedef struct {
type b_coff_optional_header (line 108) | typedef struct {
type b_coff_section_header (line 135) | typedef struct {
type b_coff_name (line 150) | typedef union {
type b_coff_external_symbol (line 160) | typedef struct {
type b_coff_internal_symbol (line 180) | typedef struct {
type debug_section_info (line 205) | struct debug_section_info
type coff_symbol (line 215) | struct coff_symbol
type coff_syminfo_data (line 225) | struct coff_syminfo_data
function coff_nodebug (line 237) | static int
function coff_nosyms (line 250) | static void
function coff_read4 (line 261) | static uint32_t
function coff_read2 (line 274) | static uint16_t
function coff_short_name_len (line 285) | static size_t
function coff_short_name_eq (line 299) | static int
function coff_long_name_eq (line 316) | static int
function coff_symbol_compare (line 327) | static int
function coff_expand_symbol (line 345) | static int
function coff_is_function_symbol (line 374) | static int
function coff_initialize_syminfo (line 383) | static int
function coff_add_syminfo_data (line 520) | static void
function coff_symbol_search (line 564) | static int
function coff_syminfo (line 582) | static void
function coff_add (line 634) | static int
type dll_notification_context (line 945) | struct dll_notification_context
function VOID (line 952) | static VOID CALLBACK
function backtrace_initialize (line 995) | int
FILE: src/vendor/libbacktrace/posix.c
function backtrace_open (line 58) | int
function backtrace_close (line 94) | int
FILE: src/vendor/libbacktrace/print.c
type print_data (line 44) | struct print_data
function error_callback (line 52) | static void
function print_syminfo_callback (line 68) | static void print_syminfo_callback (void *data, uintptr_t pc,
function print_callback (line 85) | static int
function backtrace_print (line 108) | void __attribute__((noinline))
FILE: src/vendor/libbacktrace/read.c
function backtrace_get_view (line 47) | int
function backtrace_release_view (line 101) | void
FILE: src/vendor/libbacktrace/simple.c
type backtrace_simple_data (line 42) | struct backtrace_simple_data
function _Unwind_Reason_Code (line 61) | static _Unwind_Reason_Code
function backtrace_simple (line 93) | int __attribute__((noinline))
FILE: src/vendor/libbacktrace/sort.c
function swap (line 45) | static void
function backtrace_qsort (line 60) | void
FILE: src/vendor/libbacktrace/state.c
type backtrace_state (line 45) | struct backtrace_state
type backtrace_state (line 50) | struct backtrace_state
type backtrace_state (line 51) | struct backtrace_state
type backtrace_state (line 65) | struct backtrace_state
FILE: src/vendor/libbacktrace/stest.c
type test (line 47) | struct test
type test (line 54) | struct test
function compare (line 103) | static int
function main (line 112) | int
FILE: src/vendor/libbacktrace/test_format.c
function main (line 48) | int
FILE: src/vendor/libbacktrace/testlib.c
function check (line 71) | void
function callback_one (line 106) | int
function error_callback_one (line 143) | void
function callback_two (line 157) | int
function error_callback_two (line 177) | void
function callback_three (line 191) | void
function error_callback_three (line 211) | void
function error_callback_create (line 225) | void
FILE: src/vendor/libbacktrace/testlib.h
type info (line 53) | struct info
type bdata (line 62) | struct bdata
type sdata (line 72) | struct sdata
type symdata (line 82) | struct symdata
type info (line 98) | struct info
FILE: src/vendor/libbacktrace/ttest.c
function f2 (line 63) | static int
function f3 (line 69) | static int
function test1 (line 112) | static void
function main (line 148) | int
FILE: src/vendor/libbacktrace/unittest.c
function error_callback (line 49) | static void
function test1 (line 56) | static int
function main (line 83) | int
FILE: src/vendor/libbacktrace/unknown.c
function unknown_fileline (line 42) | static int
function backtrace_initialize (line 55) | int
FILE: src/vendor/libbacktrace/xcoff.c
type b_xcoff_filhdr (line 61) | typedef struct {
type b_xcoff_filhdr (line 75) | typedef struct {
type b_xcoff_scnhdr (line 95) | typedef struct {
type b_xcoff_scnhdr (line 112) | typedef struct {
type b_xcoff_syment (line 144) | typedef struct {
type b_xcoff_syment (line 165) | typedef struct {
type b_xcoff_auxent (line 193) | typedef union {
type b_xcoff_lineno (line 238) | typedef struct {
type b_xcoff_lineno (line 250) | typedef struct {
type b_ar_fl_hdr (line 272) | typedef struct {
type b_ar_hdr (line 283) | typedef struct {
type xcoff_symbol (line 298) | struct xcoff_symbol
type xcoff_syminfo_data (line 310) | struct xcoff_syminfo_data
type xcoff_incl (line 322) | struct xcoff_incl
type xcoff_incl_vector (line 334) | struct xcoff_incl_vector
type xcoff_func (line 344) | struct xcoff_func
type xcoff_func_vector (line 365) | struct xcoff_func_vector
type xcoff_fileline_data (line 375) | struct xcoff_fileline_data
type dwsect_info (line 393) | struct dwsect_info
function xcoff_nodebug (line 405) | static int
function xcoff_nosyms (line 418) | static void
function xcoff_symbol_compare (line 429) | static int
function xcoff_symbol_search (line 445) | static int
function xcoff_add_syminfo_data (line 464) | static void
function xcoff_syminfo (line 506) | static void
function xcoff_initialize_syminfo (line 587) | static int
function xcoff_func_compare (line 652) | static int
function xcoff_func_search (line 668) | static int
function xcoff_incl_compare (line 687) | static int
function xcoff_incl_search (line 703) | static int
function xcoff_lookup_pc (line 724) | static int
function xcoff_fileline (line 812) | static int
function xcoff_initialize_fileline (line 861) | static int
function xcoff_add (line 1071) | static int
function xcoff_parse_decimal (line 1372) | static int
function xcoff_armem_add (line 1392) | static int
function xcoff_add_shared_libs (line 1476) | static void
function backtrace_initialize (line 1556) | int
FILE: src/vendor/libbacktrace/xztest.c
type xclockid_t (line 56) | typedef int xclockid_t;
function xclock_gettime (line 58) | static int
type lzma_test (line 81) | struct lzma_test
function error_callback_compress (line 92) | static void
type lzma_test (line 103) | struct lzma_test
function test_samples (line 139) | static void
function average_time (line 201) | static size_t
function test_large (line 242) | static void
function main (line 496) | int
FILE: src/vendor/libbacktrace/zstdtest.c
type xclockid_t (line 55) | typedef int xclockid_t;
function xclock_gettime (line 57) | static int
type zstd_test (line 80) | struct zstd_test
function error_callback_compress (line 91) | static void
type zstd_test (line 102) | struct zstd_test
function test_samples (line 190) | static void
function average_time (line 251) | static size_t
function test_large (line 292) | static void
function main (line 511) | int
FILE: src/vendor/libbacktrace/ztest.c
type xclockid_t (line 55) | typedef int xclockid_t;
function xclock_gettime (line 57) | static int
type zlib_test (line 80) | struct zlib_test
function error_callback_compress (line 91) | static void
type zlib_test (line 102) | struct zlib_test
function test_samples (line 189) | static void
function average_time (line 255) | static size_t
function test_large (line 296) | static void
function main (line 529) | int
FILE: tests/conftest.py
function free_port (line 14) | def free_port():
function _snapshot_skip_reason (line 22) | def _snapshot_skip_reason():
function pytest_configure (line 41) | def pytest_configure(config):
function pytest_collection_modifyitems (line 61) | def pytest_collection_modifyitems(config, items):
FILE: tests/integration/misbehaving_extension/misbehaving.cpp
function start_threads (line 26) | void start_threads(void* args)
function join_threads (line 32) | void join_threads()
function PyObject (line 37) | PyObject* dlopen_self(PyObject *, PyObject *args) {
function PyObject (line 56) | PyObject*
function PyObject (line 72) | PyObject*
type PyModuleDef (line 94) | struct PyModuleDef
function PyMODINIT_FUNC (line 96) | PyMODINIT_FUNC
FILE: tests/integration/multithreaded_extension/main.py
function foo (line 6) | def foo():
FILE: tests/integration/multithreaded_extension/testext.cpp
function allocate_memory (line 20) | void
function start_threads (line 43) | void start_threads()
function join_threads (line 53) | void join_threads()
function cleanup_handler (line 60) | __attribute__((optnone)) static void cleanup_handler(void* arg) {
function valloc_on_thread_exit (line 73) | void valloc_on_thread_exit() {
function PyObject (line 80) | PyObject*
function PyObject (line 88) | PyObject*
type PyModuleDef (line 105) | struct PyModuleDef
function PyMODINIT_FUNC (line 107) | PyMODINIT_FUNC
FILE: tests/integration/native_extension/main.py
function foo (line 6) | def foo():
FILE: tests/integration/native_extension/native_ext.c
function baz (line 15) | __attribute__((noinline)) static void baz() {
function bar (line 20) | __attribute__((noinline)) static void bar() {
function foo (line 24) | __attribute__((noinline)) static void foo() {
function PyObject (line 28) | PyObject*
function baz_inline (line 37) | __attribute__((always_inline)) static inline void baz_inline() {
function bar_inline (line 42) | __attribute__((always_inline)) static inline void bar_inline() {
function foo_inline (line 46) | __attribute__((always_inline)) static inline void foo_inline() {
function PyObject (line 50) | PyObject*
function PyObject (line 63) | PyObject*
function deep_call (line 72) | void deep_call(long n) {
function PyObject (line 79) | PyObject*
function PyObject (line 91) | PyObject*
type PyModuleDef (line 117) | struct PyModuleDef
function PyMODINIT_FUNC (line 119) | PyMODINIT_FUNC
FILE: tests/integration/rpath_extension/ext.c
function PyObject (line 5) | static PyObject *hello_world(PyObject *self, PyObject *args) {
type PyModuleDef (line 36) | struct PyModuleDef
function PyMODINIT_FUNC (line 44) | PyMODINIT_FUNC PyInit_ext(void) {
FILE: tests/integration/rpath_extension/sharedlibs/sharedlib.c
function my_shared_function (line 3) | void my_shared_function() {
FILE: tests/integration/test_api.py
function test_file_reader_as_context_manager (line 14) | def test_file_reader_as_context_manager(tmp_path):
function test_file_destination (line 31) | def test_file_destination(tmp_path):
function test_file_destination_str_path (line 47) | def test_file_destination_str_path(tmp_path):
function test_combine_destination_args (line 63) | def test_combine_destination_args():
function test_no_destination_arg (line 76) | def test_no_destination_arg():
function test_follow_fork_with_socket_destination (line 89) | def test_follow_fork_with_socket_destination():
function test_aggregated_capture_with_socket_destination (line 98) | def test_aggregated_capture_with_socket_destination():
FILE: tests/integration/test_attach.py
function generate_attach_command (line 70) | def generate_attach_command(method, output, *args):
function generate_detach_command (line 90) | def generate_detach_command(method, *args):
function run_process (line 107) | def run_process(cmd, wait_for_stderr=False):
function get_call_stack (line 154) | def get_call_stack(allocation):
function get_relevant_vallocs (line 158) | def get_relevant_vallocs(records):
function debugging_method_works (line 167) | def debugging_method_works(method):
function skip_if_not_supported (line 199) | def skip_if_not_supported(method):
function test_basic_attach (line 208) | def test_basic_attach(tmp_path, method):
function test_aggregated_attach (line 225) | def test_aggregated_attach(tmp_path, method):
function test_attach_time (line 248) | def test_attach_time(tmp_path, method):
function test_detach_without_attach (line 263) | def test_detach_without_attach(method):
FILE: tests/integration/test_extensions.py
function test_multithreaded_extension (line 21) | def test_multithreaded_extension(tmpdir, monkeypatch):
function test_misbehaving_extension (line 66) | def test_misbehaving_extension(tmpdir, monkeypatch):
function test_extension_that_uses_pygilstate_ensure (line 121) | def test_extension_that_uses_pygilstate_ensure(tmpdir, monkeypatch):
function test_native_dlopen (line 200) | def test_native_dlopen(tmpdir, monkeypatch):
function test_valloc_at_thread_exit (line 256) | def test_valloc_at_thread_exit(tmpdir, monkeypatch):
function test_valloc_at_thread_exit_in_subprocess (line 286) | def test_valloc_at_thread_exit_in_subprocess(tmpdir, monkeypatch):
function test_hard_exit (line 331) | def test_hard_exit(tmpdir, py_finalize):
function test_dlopen_with_rpath (line 363) | def test_dlopen_with_rpath(tmpdir, monkeypatch):
FILE: tests/integration/test_greenlet.py
function test_integration_with_greenlet (line 17) | def test_integration_with_greenlet(tmpdir):
function test_importing_greenlet_after_tracking_starts (line 106) | def test_importing_greenlet_after_tracking_starts(tmpdir):
function test_uninstall_profile_in_greenlet (line 199) | def test_uninstall_profile_in_greenlet(tmpdir):
FILE: tests/integration/test_ipython.py
function run_in_ipython_shell (line 9) | def run_in_ipython_shell(tmpdir, cells):
class TestIPython (line 36) | class TestIPython:
method test_ipython_profiling (line 37) | def test_ipython_profiling(self, tmpdir):
method test_exception_while_ipython_profiling (line 58) | def test_exception_while_ipython_profiling(self, tmpdir):
method test_passing_help_argument (line 82) | def test_passing_help_argument(self, tmpdir, capsys):
method test_passing_invalid_argument (line 103) | def test_passing_invalid_argument(self, tmpdir, capsys):
method test_passing_valid_arguments (line 124) | def test_passing_valid_arguments(self, tmpdir, capsys):
method test_report_title_by_report_type (line 156) | def test_report_title_by_report_type(self, tmpdir, capsys, args, title):
method test_passing_temporal_and_temporary_allocations (line 179) | def test_passing_temporal_and_temporary_allocations(self, tmpdir, caps...
FILE: tests/integration/test_main.py
function simple_test_file (line 28) | def simple_test_file(tmp_path):
function test_file_returns_from_fork (line 43) | def test_file_returns_from_fork(tmp_path):
function track_and_wait (line 56) | def track_and_wait(output_dir, sleep_after=100):
function _wait_until_process_blocks (line 84) | def _wait_until_process_blocks(pid: int) -> None:
function generate_sample_results (line 117) | def generate_sample_results(
class TestRunSubcommand (line 149) | class TestRunSubcommand:
method test_run (line 150) | def test_run(self, tmp_path, simple_test_file):
method test_run_override_output (line 174) | def test_run_override_output(self, tmp_path, simple_test_file):
method test_run_overwrite_output_file (line 199) | def test_run_overwrite_output_file(self, tmp_path, simple_test_file):
method test_run_file_with_args (line 229) | def test_run_file_with_args(self, tmp_path):
method test_sys_manipulations_when_running_script (line 269) | def test_sys_manipulations_when_running_script(self, tmp_path):
method test_suppressing_sys_manipulations_when_running_script (line 305) | def test_suppressing_sys_manipulations_when_running_script(
method test_sys_manipulations_when_running_module (line 342) | def test_sys_manipulations_when_running_module(self, tmp_path):
method test_suppressing_sys_manipulations_when_running_module (line 377) | def test_suppressing_sys_manipulations_when_running_module(
method test_sys_manipulations_when_running_cmd (line 413) | def test_sys_manipulations_when_running_cmd(self, tmp_path):
method test_suppressing_sys_manipulations_when_running_cmd (line 446) | def test_suppressing_sys_manipulations_when_running_cmd(
method test_run_file_that_is_not_python (line 481) | def test_run_file_that_is_not_python(self, capsys, option):
method test_run_file_exists (line 495) | def test_run_file_exists(self, getpid, tmp_path, monkeypatch, capsys):
method test_run_output_file_directory_does_not_exist (line 509) | def test_run_output_file_directory_does_not_exist(self, capsys):
method test_quiet (line 520) | def test_quiet(self, quiet, tmp_path, simple_test_file):
method test_not_quiet_and_fork (line 549) | def test_not_quiet_and_fork(self, tmp_path, test_file_returns_from_fork):
class TestParseSubcommand (line 575) | class TestParseSubcommand:
method test_successful_parse (line 576) | def test_successful_parse(self, tmp_path):
method test_successful_parse_of_aggregated_capture_file (line 633) | def test_successful_parse_of_aggregated_capture_file(self, tmp_path):
method test_error_when_stdout_is_a_tty (line 693) | def test_error_when_stdout_is_a_tty(self, tmp_path, simple_test_file):
method test_error_when_input_file_does_not_exist (line 719) | def test_error_when_input_file_does_not_exist(self, tmp_path):
class TestFlamegraphSubCommand (line 742) | class TestFlamegraphSubCommand:
method test_reads_from_correct_file (line 743) | def test_reads_from_correct_file(self, tmp_path, simple_test_file):
method test_no_web_embeds_d3_assets (line 769) | def test_no_web_embeds_d3_assets(self, tmp_path, simple_test_file):
method test_can_generate_reports_with_native_traces (line 799) | def test_can_generate_reports_with_native_traces(self, tmp_path, simpl...
method test_writes_to_correct_file (line 825) | def test_writes_to_correct_file(self, tmp_path, simple_test_file):
method test_output_file_already_exists (line 852) | def test_output_file_already_exists(self, tmp_path, simple_test_file, ...
method test_split_threads_subcommand (line 871) | def test_split_threads_subcommand(self, tmp_path, simple_test_file):
method test_leaks_with_pymalloc_warning (line 901) | def test_leaks_with_pymalloc_warning(
class TestSummarySubCommand (line 946) | class TestSummarySubCommand:
method test_summary_generated (line 947) | def test_summary_generated(self, tmp_path, simple_test_file):
method test_temporary_allocations_summary (line 969) | def test_temporary_allocations_summary(self, tmp_path, simple_test_file):
class TestTreeSubCommand (line 991) | class TestTreeSubCommand:
method test_tree_generated (line 992) | def test_tree_generated(self, tmp_path, simple_test_file):
method test_temporary_allocations_tree (line 1018) | def test_temporary_allocations_tree(self, tmp_path, simple_test_file):
class TestStatsSubCommand (line 1044) | class TestStatsSubCommand:
method test_report_generated (line 1045) | def test_report_generated(self, tmp_path, simple_test_file):
method test_json_generated (line 1067) | def test_json_generated(self, tmp_path, simple_test_file):
method test_json_generated_to_pretty_file_name (line 1090) | def test_json_generated_to_pretty_file_name(self, tmp_path, simple_tes...
method test_json_generated_to_known_file (line 1115) | def test_json_generated_to_known_file(self, tmp_path, simple_test_file):
method test_json_generated_to_existing_known_file (line 1140) | def test_json_generated_to_existing_known_file(self, tmp_path, simple_...
method test_json_overwrites_existing_known_file (line 1171) | def test_json_overwrites_existing_known_file(self, tmp_path, simple_te...
method test_report_detects_corrupt_input (line 1199) | def test_report_detects_corrupt_input(self, tmp_path):
class TestTableSubCommand (line 1222) | class TestTableSubCommand:
method test_reads_from_correct_file (line 1223) | def test_reads_from_correct_file(self, tmp_path, simple_test_file):
method test_no_split_threads (line 1249) | def test_no_split_threads(self, tmp_path):
class TestReporterSubCommands (line 1268) | class TestReporterSubCommands:
method test_report_detects_missing_input (line 1272) | def test_report_detects_missing_input(self, report):
method test_report_detects_corrupt_input (line 1291) | def test_report_detects_corrupt_input(self, tmp_path, report):
method test_report_leaks_argument (line 1316) | def test_report_leaks_argument(self, tmp_path, simple_test_file, report):
method test_report_temporary_allocations_argument (line 1343) | def test_report_temporary_allocations_argument(
method test_report_incompatible_arguments (line 1372) | def test_report_incompatible_arguments(self, tmp_path, simple_test_fil...
method test_report_both_temporary_allocation_arguments (line 1399) | def test_report_both_temporary_allocation_arguments(
class TestLiveRemoteSubcommand (line 1429) | class TestLiveRemoteSubcommand:
method test_live_tracking (line 1430) | def test_live_tracking(self, tmp_path, simple_test_file, free_port):
method test_live_tracking_waits_for_client (line 1480) | def test_live_tracking_waits_for_client(self, simple_test_file):
method test_run_live_tracking_invalid_port (line 1502) | def test_run_live_tracking_invalid_port(self, simple_test_file, port):
method test_live_tracking_invalid_port (line 1527) | def test_live_tracking_invalid_port(self, port):
method test_live_tracking_server_when_client_disconnects (line 1548) | def test_live_tracking_server_when_client_disconnects(self, free_port,...
method test_live_tracking_server_exits_properly_on_sigint (line 1604) | def test_live_tracking_server_exits_properly_on_sigint(self, simple_te...
method test_live_client_exits_properly_on_sigint_before_connecting (line 1642) | def test_live_client_exits_properly_on_sigint_before_connecting(self, ...
class TestLiveSubcommand (line 1673) | class TestLiveSubcommand:
method test_live_tracking (line 1674) | def test_live_tracking(self, tmp_path):
class TestTransformSubCommands (line 1702) | class TestTransformSubCommands:
method test_report_detects_missing_input (line 1703) | def test_report_detects_missing_input(self):
method test_report_detects_corrupt_input (line 1722) | def test_report_detects_corrupt_input(self, tmp_path):
method test_report_leaks_argument (line 1747) | def test_report_leaks_argument(self, tmp_path, simple_test_file):
FILE: tests/integration/test_native_tracking.py
function test_multithreaded_extension_with_native_tracking (line 23) | def test_multithreaded_extension_with_native_tracking(tmpdir, monkeypatch):
function test_simple_call_chain_with_native_tracking (line 78) | def test_simple_call_chain_with_native_tracking(tmpdir, monkeypatch):
function test_inlined_call_chain_with_native_tracking (line 123) | def test_inlined_call_chain_with_native_tracking(tmpdir, monkeypatch):
function test_deep_call_chain_with_native_tracking (line 165) | def test_deep_call_chain_with_native_tracking(tmpdir, monkeypatch):
function test_hybrid_stack_in_pure_python (line 209) | def test_hybrid_stack_in_pure_python(tmpdir):
function test_hybrid_stack_in_pure_python_with_callbacks (line 257) | def test_hybrid_stack_in_pure_python_with_callbacks(tmpdir):
function test_hybrid_stack_of_allocations_inside_ceval (line 317) | def test_hybrid_stack_of_allocations_inside_ceval(tmpdir):
function test_hybrid_stack_in_recursive_python_c_call (line 391) | def test_hybrid_stack_in_recursive_python_c_call(tmpdir, monkeypatch):
function test_hybrid_stack_in_a_thread (line 448) | def test_hybrid_stack_in_a_thread(tmpdir, monkeypatch):
function test_hybrid_stack_of_python_thread_starts_with_native_frames (line 485) | def test_hybrid_stack_of_python_thread_starts_with_native_frames(tmp_path):
function test_native_tracing_header (line 514) | def test_native_tracing_header(native_traces, tmpdir):
FILE: tests/integration/test_object_tracking.py
class MyClass (line 22) | class MyClass:
method __init__ (line 23) | def __init__(self, name):
function test_track_object_lifetimes_version_check (line 29) | def test_track_object_lifetimes_version_check(tmp_path):
function test_get_surviving_objects_version_check (line 46) | def test_get_surviving_objects_version_check(tmp_path):
function test_get_tracked_objects_version_check (line 62) | def test_get_tracked_objects_version_check(tmp_path):
function test_track_object_lifetimes_disabled_by_default (line 81) | def test_track_object_lifetimes_disabled_by_default(tmp_path):
function test_track_object_lifetimes_simple_object (line 100) | def test_track_object_lifetimes_simple_object(tmp_path):
function test_track_object_lifetimes_deallocated_object (line 139) | def test_track_object_lifetimes_deallocated_object(tmp_path):
function test_track_object_lifetimes_with_stack_trace (line 194) | def test_track_object_lifetimes_with_stack_trace(tmp_path):
function test_multiple_surviving_objects (line 247) | def test_multiple_surviving_objects(tmp_path):
function test_object_tracking_in_threads (line 288) | def test_object_tracking_in_threads(tmp_path):
function test_object_stack_trace_with_native_traces (line 340) | def test_object_stack_trace_with_native_traces(tmp_path):
function test_get_tracked_objects_without_filter (line 389) | def test_get_tracked_objects_without_filter(tmp_path):
function test_track_object_lifetimes_aggregating_writer (line 445) | def test_track_object_lifetimes_aggregating_writer(tmp_path):
function test_track_object_lifetimes_fails_before_tracking_starts (line 511) | def test_track_object_lifetimes_fails_before_tracking_starts(tmp_path):
function test_track_object_lifetimes_fails_before_tracking_ends (line 527) | def test_track_object_lifetimes_fails_before_tracking_ends(tmp_path):
FILE: tests/integration/test_processes.py
function set_multiprocessing_to_fork (line 19) | def set_multiprocessing_to_fork():
function multiproc_func (line 26) | def multiproc_func(repetitions): # pragma: no cover
function pymalloc_multiproc_func (line 33) | def pymalloc_multiproc_func(): # pragma: no cover
function test_allocations_with_multiprocessing (line 40) | def test_allocations_with_multiprocessing(tmpdir):
function test_allocations_with_multiprocessing_following_fork (line 78) | def test_allocations_with_multiprocessing_following_fork(tmpdir):
function test_pymalloc_allocations_after_fork (line 138) | def test_pymalloc_allocations_after_fork(tmpdir):
function test_stack_cleanup_after_fork (line 169) | def test_stack_cleanup_after_fork(tmpdir):
FILE: tests/integration/test_record_writer.py
function get_sample_line_number_tables (line 17) | def get_sample_line_number_tables():
function parse_capture_file (line 59) | def parse_capture_file(output_file):
function sort_runs_of_same_record_type (line 72) | def sort_runs_of_same_record_type(records):
function test_write_basic_records (line 79) | def test_write_basic_records(tmp_path):
function test_write_aggregated_records (line 198) | def test_write_aggregated_records(tmp_path):
function test_decoding_line_numbers (line 277) | def test_decoding_line_numbers(tmp_path):
function test_write_object_tracking_records (line 306) | def test_write_object_tracking_records(tmp_path):
function test_write_object_tracking_records_aggregated (line 353) | def test_write_object_tracking_records_aggregated(tmp_path):
FILE: tests/integration/test_socket.py
function run_till_snapshot_point (line 89) | def run_till_snapshot_point(
class TestSocketReaderErrorHandling (line 145) | class TestSocketReaderErrorHandling:
method test_get_current_snapshot_raises_before_context (line 147) | def test_get_current_snapshot_raises_before_context(self, free_port: i...
method test_get_is_active_after_context (line 155) | def test_get_is_active_after_context(self, free_port: int, tmp_path: P...
method test_get_current_snapshot_raises_after_context (line 173) | def test_get_current_snapshot_raises_after_context(
method test_get_current_snapshot_first_yield_after_context_raises (line 194) | def test_get_current_snapshot_first_yield_after_context_raises(
method test_nested_context_is_diallowed (line 215) | def test_nested_context_is_diallowed(self, free_port: int, tmp_path: P...
class TestSocketReaderAccess (line 235) | class TestSocketReaderAccess:
method test_empty_snapshot_after_free (line 237) | def test_empty_snapshot_after_free(self, free_port: int, tmp_path: Pat...
method test_single_allocation_snapshot (line 256) | def test_single_allocation_snapshot(self, free_port: int, tmp_path: Pa...
method test_multi_allocation_snapshot (line 284) | def test_multi_allocation_snapshot(self, free_port: int, tmp_path: Pat...
method test_multiple_context_entries_does_not_crash (line 312) | def test_multiple_context_entries_does_not_crash(
method test_command_line (line 342) | def test_command_line(self, free_port: int, tmp_path: Path) -> None:
method test_reading_allocations_while_reading_stack_traces (line 362) | def test_reading_allocations_while_reading_stack_traces(
FILE: tests/integration/test_threads.py
function allocating_function (line 16) | def allocating_function(allocator, flag_event, wait_event):
function test_thread_allocations_after_tracker_is_deactivated (line 25) | def test_thread_allocations_after_tracker_is_deactivated(tmpdir):
function test_thread_name (line 66) | def test_thread_name(tmpdir):
function test_setting_python_thread_name (line 99) | def test_setting_python_thread_name(tmpdir):
FILE: tests/integration/test_tracing.py
function alloc_func3 (line 18) | def alloc_func3(allocator):
function alloc_func2 (line 27) | def alloc_func2(allocator):
function alloc_func1 (line 34) | def alloc_func1(allocator):
function test_traceback (line 41) | def test_traceback(tmpdir):
function test_traceback_for_high_watermark (line 75) | def test_traceback_for_high_watermark(tmpdir):
function test_traceback_iteration_does_not_depend_on_the_order_of_elements (line 100) | def test_traceback_iteration_does_not_depend_on_the_order_of_elements(tm...
function test_cython_traceback (line 126) | def test_cython_traceback(tmpdir):
function test_large_number_of_frame_pops_between_subsequent_allocations (line 166) | def test_large_number_of_frame_pops_between_subsequent_allocations(tmpdir):
function test_records_can_be_retrieved_twice (line 210) | def test_records_can_be_retrieved_twice(tmpdir):
function test_high_watermark_records_can_be_retrieved_twice (line 229) | def test_high_watermark_records_can_be_retrieved_twice(tmpdir):
function test_traceback_can_be_retrieved_twice (line 248) | def test_traceback_can_be_retrieved_twice(tmpdir):
function test_traceback_for_high_watermark_records_can_be_retrieved_twice (line 268) | def test_traceback_for_high_watermark_records_can_be_retrieved_twice(tmp...
function test_profile_function_is_restored_after_tracking (line 291) | def test_profile_function_is_restored_after_tracking(tmpdir):
function test_initial_tracking_frames_are_correctly_populated (line 309) | def test_initial_tracking_frames_are_correctly_populated(tmpdir):
function test_restart_tracing_function_gets_correctly_the_frames (line 337) | def test_restart_tracing_function_gets_correctly_the_frames(tmpdir):
function test_num_records (line 377) | def test_num_records(tmpdir):
function test_allocations_in_root_frame_have_correct_line_number (line 394) | def test_allocations_in_root_frame_have_correct_line_number(tmpdir):
function test_equal_stack_traces_compare_equal (line 426) | def test_equal_stack_traces_compare_equal(tmpdir):
function test_identical_stack_traces_started_in_different_lines_in_the_root_do_not_compare_equal (line 455) | def test_identical_stack_traces_started_in_different_lines_in_the_root_d...
function test_identical_stack_traces_started_in_different_lines_in_a_function_do_not_compare_equal (line 488) | def test_identical_stack_traces_started_in_different_lines_in_a_function...
function test_allocation_in_thread_started_before_tracking_starts (line 523) | def test_allocation_in_thread_started_before_tracking_starts(tmp_path):
function test_allocation_in_thread_before_reacquiring_gil_after_tracking_starts (line 583) | def test_allocation_in_thread_before_reacquiring_gil_after_tracking_star...
function test_thread_surviving_multiple_trackers (line 630) | def test_thread_surviving_multiple_trackers(tmp_path):
function test_thread_surviving_multiple_trackers_with_changing_callstack (line 677) | def test_thread_surviving_multiple_trackers_with_changing_callstack(tmp_...
function test_cython_frame_in_pre_existing_thread_stack (line 762) | def test_cython_frame_in_pre_existing_thread_stack(tmp_path):
function test_cython_frame_in_pre_existing_thread_stack_when_restarting_tracking (line 827) | def test_cython_frame_in_pre_existing_thread_stack_when_restarting_track...
function test_allocation_after_unsetting_profile_function (line 899) | def test_allocation_after_unsetting_profile_function(tmp_path):
function test_allocation_in_thread_after_unsetting_profile_function (line 941) | def test_allocation_in_thread_after_unsetting_profile_function(tmp_path):
class TestMmap (line 981) | class TestMmap:
method allocating_function (line 983) | def allocating_function(cls):
method test_mmap (line 988) | def test_mmap(self, tmpdir):
method test_mmap_in_thread (line 1017) | def test_mmap_in_thread(self, tmpdir):
FILE: tests/integration/test_tracking.py
function test_no_allocations_while_tracking (line 62) | def test_no_allocations_while_tracking(tmp_path):
function test_simple_allocation_tracking (line 72) | def test_simple_allocation_tracking(allocator_func, allocator_type, tmp_...
function test_simple_cpp_allocation_tracking (line 104) | def test_simple_cpp_allocation_tracking(tmp_path):
function test_simple_pymalloc_allocation_tracking (line 128) | def test_simple_pymalloc_allocation_tracking(
function test_pymalloc_allocation_tracking_deactivated (line 166) | def test_pymalloc_allocation_tracking_deactivated(
function test_mmap_tracking (line 193) | def test_mmap_tracking(tmp_path):
function test_pthread_tracking (line 216) | def test_pthread_tracking(tmp_path):
function test_tracking_with_SIGKILL (line 247) | def test_tracking_with_SIGKILL(tmpdir):
function test_no_allocations (line 295) | def test_no_allocations(tmpdir):
function test_unsupported_operations_on_aggregated_capture (line 320) | def test_unsupported_operations_on_aggregated_capture(tmpdir):
class TestHighWatermark (line 365) | class TestHighWatermark:
method test_no_allocations_while_tracking (line 366) | def test_no_allocations_while_tracking(self, tmp_path, file_format):
method test_simple_allocation_tracking (line 384) | def test_simple_allocation_tracking(
method test_multiple_high_watermark (line 415) | def test_multiple_high_watermark(self, tmp_path, file_format):
method test_freed_before_high_watermark_do_not_appear (line 451) | def test_freed_before_high_watermark_do_not_appear(self, tmp_path, fil...
method test_freed_after_high_watermark_do_not_appear (line 489) | def test_freed_after_high_watermark_do_not_appear(self, tmp_path, file...
method test_allocations_aggregation_on_same_line (line 527) | def test_allocations_aggregation_on_same_line(self, tmp_path, file_for...
method test_aggregation_same_python_stack_and_same_native_stack (line 562) | def test_aggregation_same_python_stack_and_same_native_stack(
method test_allocations_aggregation_on_different_lines (line 599) | def test_allocations_aggregation_on_different_lines(self, tmp_path, fi...
method test_aggregation_same_python_stack_but_different_native_stack (line 628) | def test_aggregation_same_python_stack_but_different_native_stack(
method test_non_freed_allocations_are_accounted_for (line 656) | def test_non_freed_allocations_are_accounted_for(self, tmp_path, file_...
method test_final_allocation_is_peak (line 685) | def test_final_allocation_is_peak(self, tmp_path, file_format):
method test_spiky_generally_increasing_to_final_peak (line 717) | def test_spiky_generally_increasing_to_final_peak(self, tmp_path, file...
method test_allocations_after_high_watermark_is_freed_do_not_appear (line 764) | def test_allocations_after_high_watermark_is_freed_do_not_appear(
method test_partial_munmap (line 804) | def test_partial_munmap(self, tmp_path, file_format):
method test_partial_munmap_gap (line 836) | def test_partial_munmap_gap(self, tmp_path, file_format):
method test_munmap_multiple_mmaps (line 869) | def test_munmap_multiple_mmaps(self, tmp_path, file_format):
method test_munmap_multiple_mmaps_multiple_munmaps (line 903) | def test_munmap_multiple_mmaps_multiple_munmaps(self, tmp_path, file_f...
method test_partial_munmap_multiple_split_in_middle (line 937) | def test_partial_munmap_multiple_split_in_middle(self, tmp_path, file_...
method test_partial_munmap_split_in_middle (line 962) | def test_partial_munmap_split_in_middle(self, tmp_path, file_format):
class TestLeaks (line 995) | class TestLeaks:
method test_leaks_allocations_are_detected (line 996) | def test_leaks_allocations_are_detected(self, tmp_path, file_format):
method test_allocations_that_are_freed_do_not_appear_as_leaks (line 1025) | def test_allocations_that_are_freed_do_not_appear_as_leaks(
method test_leak_that_happens_in_the_middle_is_detected (line 1055) | def test_leak_that_happens_in_the_middle_is_detected(self, tmp_path, f...
method test_leaks_that_happen_in_different_lines (line 1092) | def test_leaks_that_happen_in_different_lines(self, tmp_path, file_for...
method test_leaks_that_happen_in_the_same_function_are_aggregated (line 1116) | def test_leaks_that_happen_in_the_same_function_are_aggregated(
method test_unmatched_deallocations_are_not_reported (line 1153) | def test_unmatched_deallocations_are_not_reported(self, tmp_path, file...
method test_thread_allocations_multiple_threads (line 1174) | def test_thread_allocations_multiple_threads(self, tmpdir, file_format):
class TestTemporaryAllocations (line 1232) | class TestTemporaryAllocations:
method test_temporary_allocations_are_detected (line 1233) | def test_temporary_allocations_are_detected(self, tmp_path):
method test_temporary_allocations_with_two_allocators_are_detected (line 1260) | def test_temporary_allocations_with_two_allocators_are_detected(self, ...
method test_temporary_allocations_outside_buffer_are_not_detected (line 1298) | def test_temporary_allocations_outside_buffer_are_not_detected(
method test_temporary_allocations_that_happen_in_different_lines (line 1328) | def test_temporary_allocations_that_happen_in_different_lines(self, tm...
method test_temporary_allocations_that_happen_in_the_same_function_are_aggregated (line 1351) | def test_temporary_allocations_that_happen_in_the_same_function_are_ag...
method test_unmatched_allocations_are_not_reported (line 1382) | def test_unmatched_allocations_are_not_reported(self, tmp_path):
method test_thread_allocations_multiple_threads (line 1400) | def test_thread_allocations_multiple_threads(self, tmpdir):
method test_intertwined_temporary_allocations_in_threads (line 1455) | def test_intertwined_temporary_allocations_in_threads(self, tmpdir):
class TestHeader (line 1530) | class TestHeader:
method test_get_header (line 1531) | def test_get_header(self, monkeypatch, tmpdir):
method test_get_header_after_snapshot (line 1561) | def test_get_header_after_snapshot(self, monkeypatch, tmpdir):
method test_header_allocator (line 1602) | def test_header_allocator(self, allocator, allocator_name, tmpdir):
function test_pymalloc_with_python_stack_traces (line 1633) | def test_pymalloc_with_python_stack_traces(tmp_path):
class TestMemorySnapshots (line 1679) | class TestMemorySnapshots:
method test_memory_snapshots_are_written (line 1681) | def test_memory_snapshots_are_written(self, tmp_path):
method test_memory_snapshots_tick_interval (line 1703) | def test_memory_snapshots_tick_interval(self, tmp_path):
method test_memory_snapshots_limit_when_reading (line 1724) | def test_memory_snapshots_limit_when_reading(self, tmp_path):
method test_temporary_allocations_when_filling_vector_without_preallocating (line 1752) | def test_temporary_allocations_when_filling_vector_without_preallocating(
method test_temporary_allocations_when_filling_vector_without_preallocating_small_buffer (line 1776) | def test_temporary_allocations_when_filling_vector_without_preallocati...
FILE: tests/test_utils.py
class TestFilterRelevantAllocations (line 9) | class TestFilterRelevantAllocations:
method test_filters_for_valloc_and_free (line 10) | def test_filters_for_valloc_and_free(self):
method test_filters_based_on_addresses (line 21) | def test_filters_based_on_addresses(self):
method test_free_records_with_valid_addresses_that_dont_match_do_not_appear (line 33) | def test_free_records_with_valid_addresses_that_dont_match_do_not_appe...
method test_free_records_with_unmatched_addresses_do_not_appear (line 47) | def test_free_records_with_unmatched_addresses_do_not_appear(self):
class TestMockAllocationRecord (line 62) | class TestMockAllocationRecord:
method test_holds_values_at_correct_names (line 63) | def test_holds_values_at_correct_names(self):
method test_looks_like_AllocationRecord (line 84) | def test_looks_like_AllocationRecord(self):
method test_equality (line 107) | def test_equality(self):
FILE: tests/unit/conftest.py
function use_80_columns (line 5) | def use_80_columns(monkeypatch):
FILE: tests/unit/test_allocation_lifetime_aggregator.py
class Location (line 14) | class Location:
function test_no_allocations_at_start (line 21) | def test_no_allocations_at_start():
function test_allocation_not_reported_when_freed_within_same_snapshot (line 30) | def test_allocation_not_reported_when_freed_within_same_snapshot():
function test_allocation_reported_when_freed_within_different_snapshot (line 48) | def test_allocation_reported_when_freed_within_different_snapshot():
function test_allocation_reported_when_leaked (line 73) | def test_allocation_reported_when_leaked():
function test_multiple_snapshots_between_allocation_and_deallocation (line 96) | def test_multiple_snapshots_between_allocation_and_deallocation():
function test_allocations_from_same_location_and_snapshot_freed_in_different_snapshots (line 126) | def test_allocations_from_same_location_and_snapshot_freed_in_different_...
function test_allocations_from_same_location_and_different_snapshots_freed_in_one_snapshot (line 155) | def test_allocations_from_same_location_and_different_snapshots_freed_in...
function test_two_leaked_allocations_from_one_location (line 183) | def test_two_leaked_allocations_from_one_location():
function test_allocations_made_and_freed_together_are_aggregated (line 209) | def test_allocations_made_and_freed_together_are_aggregated():
function test_leaked_allocations_within_one_snapshot_are_aggregated (line 236) | def test_leaked_allocations_within_one_snapshot_are_aggregated():
function test_freed_allocations_from_different_locations_are_not_aggregated (line 261) | def test_freed_allocations_from_different_locations_are_not_aggregated():
function test_leaked_allocations_from_different_locations_are_not_aggregated (line 307) | def test_leaked_allocations_from_different_locations_are_not_aggregated():
function test_range_freed_in_same_snapshot (line 344) | def test_range_freed_in_same_snapshot():
function test_range_freed_in_different_snapshot (line 362) | def test_range_freed_in_different_snapshot():
function test_range_leaked (line 387) | def test_range_leaked():
function test_shrunk_then_leaked_range (line 410) | def test_shrunk_then_leaked_range():
function test_shrunk_then_freed_range (line 434) | def test_shrunk_then_freed_range():
function test_split_then_leaked_range (line 461) | def test_split_then_leaked_range():
function test_split_then_freed_range (line 487) | def test_split_then_freed_range():
FILE: tests/unit/test_attach.py
class TestAttachSubCommand (line 9) | class TestAttachSubCommand:
method test_memray_attach_aggregated_without_output_file (line 10) | def test_memray_attach_aggregated_without_output_file(
FILE: tests/unit/test_cli.py
function test_no_args_passed (line 20) | def test_no_args_passed(capsys):
class TestRunSubCommand (line 33) | class TestRunSubCommand:
method test_run_without_arguments (line 34) | def test_run_without_arguments(
method test_run_default_output (line 43) | def test_run_default_output(
method test_run_with_native_mode (line 56) | def test_run_with_native_mode(
method test_run_with_pymalloc_tracing (line 69) | def test_run_with_pymalloc_tracing(
method test_run_override_output (line 83) | def test_run_override_output(
method test_run_overwrite_output_file (line 95) | def test_run_overwrite_output_file(
method test_run_module (line 107) | def test_run_module(self, getpid_mock, runpy_mock, tracker_mock, valid...
method test_run_cmd_is_validated (line 113) | def test_run_cmd_is_validated(
method test_run_cmd (line 121) | def test_run_cmd(self, getpid_mock, runpy_mock, tracker_mock, validate...
method test_run_file (line 129) | def test_run_file(self, getpid_mock, runpy_mock, tracker_mock, validat...
method test_run_relative_file (line 134) | def test_run_relative_file(
method test_run_with_live (line 153) | def test_run_with_live(
method test_run_with_live_and_trace_python_allocators (line 185) | def test_run_with_live_and_trace_python_allocators(
method test_run_with_live_remote (line 224) | def test_run_with_live_remote(
method test_run_with_live_remote_and_live_port (line 241) | def test_run_with_live_remote_and_live_port(
method test_run_with_live_port_but_not_live_remote (line 264) | def test_run_with_live_port_but_not_live_remote(
method test_run_with_follow_fork (line 273) | def test_run_with_follow_fork(
method test_run_with_follow_fork_and_live_mode (line 291) | def test_run_with_follow_fork_and_live_mode(
method test_run_with_follow_fork_and_live_remote_mode (line 300) | def test_run_with_follow_fork_and_live_remote_mode(
method test_run_with_trace_python_allocators_and_live_remote_mode (line 309) | def test_run_with_trace_python_allocators_and_live_remote_mode(
class TestFlamegraphSubCommand (line 335) | class TestFlamegraphSubCommand:
method get_prepared_parser (line 337) | def get_prepared_parser():
method test_parser_rejects_no_arguments (line 344) | def test_parser_rejects_no_arguments(self):
method test_parser_rejects_when_no_results_provided (line 352) | def test_parser_rejects_when_no_results_provided(self):
method test_parser_accepts_single_argument (line 360) | def test_parser_accepts_single_argument(self):
method test_parser_accepts_short_form_output_1 (line 372) | def test_parser_accepts_short_form_output_1(self):
method test_parser_accepts_short_form_output_2 (line 384) | def test_parser_accepts_short_form_output_2(self):
method test_parser_accepts_long_form_output_1 (line 396) | def test_parser_accepts_long_form_output_1(self):
method test_parser_accepts_long_form_output_2 (line 408) | def test_parser_accepts_long_form_output_2(self):
method test_parser_takes_memory_leaks_as_a_flag (line 420) | def test_parser_takes_memory_leaks_as_a_flag(self):
method test_parser_takes_force_flag (line 434) | def test_parser_takes_force_flag(self):
function test_determine_output (line 475) | def test_determine_output(input, expected, factory):
class TestTreeSubCommand (line 483) | class TestTreeSubCommand:
method get_prepared_parser (line 485) | def get_prepared_parser():
method test_parser_rejects_no_arguments (line 492) | def test_parser_rejects_no_arguments(self):
method test_parser_rejects_when_no_results_provided (line 500) | def test_parser_rejects_when_no_results_provided(self):
method test_parser_accepts_single_argument (line 508) | def test_parser_accepts_single_argument(self):
method test_parser_acceps_biggest_allocs_short_form (line 519) | def test_parser_acceps_biggest_allocs_short_form(self):
method test_parser_acceps_biggest_allocs_long_form (line 530) | def test_parser_acceps_biggest_allocs_long_form(self):
class TestTableSubCommand (line 542) | class TestTableSubCommand:
method get_prepared_parser (line 544) | def get_prepared_parser():
method test_parser_rejects_no_arguments (line 551) | def test_parser_rejects_no_arguments(self):
method test_parser_rejects_when_no_results_provided (line 559) | def test_parser_rejects_when_no_results_provided(self):
method test_parser_accepts_single_argument (line 567) | def test_parser_accepts_single_argument(self):
method test_parser_accepts_short_form_output_1 (line 578) | def test_parser_accepts_short_form_output_1(self):
method test_parser_accepts_short_form_output_2 (line 590) | def test_parser_accepts_short_form_output_2(self):
method test_parser_accepts_long_form_output_1 (line 602) | def test_parser_accepts_long_form_output_1(self):
method test_parser_accepts_long_form_output_2 (line 614) | def test_parser_accepts_long_form_output_2(self):
method test_parser_takes_memory_leaks_as_a_flag (line 626) | def test_parser_takes_memory_leaks_as_a_flag(self):
method test_parser_takes_force_flag (line 640) | def test_parser_takes_force_flag(self):
class TestSummarySubCommand (line 655) | class TestSummarySubCommand:
method get_prepared_parser (line 657) | def get_prepared_parser():
method test_parser_rejects_no_arguments (line 664) | def test_parser_rejects_no_arguments(self):
method test_parser_accepts_single_argument (line 672) | def test_parser_accepts_single_argument(self):
method test_parser_accepts_sort_column_long_form (line 684) | def test_parser_accepts_sort_column_long_form(self):
method test_parser_accepts_sort_column_sort_form (line 696) | def test_parser_accepts_sort_column_sort_form(self):
method test_parser_rejects_sort_column_incorrect_values (line 709) | def test_parser_rejects_sort_column_incorrect_values(self, column):
method test_parser_accepts_max_rows_long_form (line 719) | def test_parser_accepts_max_rows_long_form(self):
method test_parser_accepts_max_rows_sort_form (line 731) | def test_parser_accepts_max_rows_sort_form(self):
class TestStatsSubCommand (line 744) | class TestStatsSubCommand:
method get_prepared_parser (line 746) | def get_prepared_parser():
method test_parser_rejects_no_arguments (line 753) | def test_parser_rejects_no_arguments(self):
method test_parser_accepts_single_argument (line 761) | def test_parser_accepts_single_argument(self):
method test_parser_accepts_valid_num_largest_allocators (line 772) | def test_parser_accepts_valid_num_largest_allocators(self):
method test_parser_rejects_invalid_num_largest_allocators (line 783) | def test_parser_rejects_invalid_num_largest_allocators(self):
class TestTransformSubCommand (line 792) | class TestTransformSubCommand:
method get_prepared_parser (line 794) | def get_prepared_parser():
method test_parser_rejects_no_arguments (line 801) | def test_parser_rejects_no_arguments(self):
method test_parser_rejects_when_no_results_provided (line 809) | def test_parser_rejects_when_no_results_provided(self):
method test_parser_invalid_format (line 817) | def test_parser_invalid_format(self):
method test_parser_accepts_single_argument_with_format (line 825) | def test_parser_accepts_single_argument_with_format(self):
method test_parser_accepts_short_form_output_1 (line 837) | def test_parser_accepts_short_form_output_1(self):
method test_parser_accepts_short_form_output_2 (line 850) | def test_parser_accepts_short_form_output_2(self):
method test_parser_accepts_long_form_output_1 (line 863) | def test_parser_accepts_long_form_output_1(self):
method test_parser_accepts_long_form_output_2 (line 878) | def test_parser_accepts_long_form_output_2(self):
method test_parser_takes_memory_leaks_as_a_flag (line 893) | def test_parser_takes_memory_leaks_as_a_flag(self):
method test_parser_takes_force_flag (line 908) | def test_parser_takes_force_flag(self):
FILE: tests/unit/test_flamegraph_reporter.py
function packed_data_to_tree (line 13) | def packed_data_to_tree(packed_data):
function get_packed_trees (line 50) | def get_packed_trees(packed_data):
class TestFlameGraphReporter (line 72) | class TestFlameGraphReporter:
method test_works_with_no_allocations (line 73) | def test_works_with_no_allocations(self):
method test_inverted_works_with_no_allocations (line 83) | def test_inverted_works_with_no_allocations(self):
method test_works_with_single_call (line 93) | def test_works_with_single_call(self):
method test_inverted_works_with_single_call (line 166) | def test_inverted_works_with_single_call(self):
method test_uses_hybrid_stack_for_native_traces (line 239) | def test_uses_hybrid_stack_for_native_traces(self):
method test_inverted_uses_hybrid_stack_for_native_traces (line 311) | def test_inverted_uses_hybrid_stack_for_native_traces(self):
method test_works_with_multiple_stacks_from_same_caller (line 384) | def test_works_with_multiple_stacks_from_same_caller(self):
method test_sanity_check_with_real_allocations (line 479) | def test_sanity_check_with_real_allocations(self, tmp_path):
method test_inverted_sanity_check_with_real_allocations (line 509) | def test_inverted_sanity_check_with_real_allocations(self, tmp_path):
method test_works_with_multiple_stacks_from_same_caller_two_frames_above (line 542) | def test_works_with_multiple_stacks_from_same_caller_two_frames_above(...
method test_inverted_works_with_multiple_stacks_from_same_caller_two_frames_above (line 648) | def test_inverted_works_with_multiple_stacks_from_same_caller_two_fram...
method test_works_with_recursive_calls (line 767) | def test_works_with_recursive_calls(self):
method test_inverted_works_with_recursive_calls (line 899) | def test_inverted_works_with_recursive_calls(self):
method test_works_with_multiple_top_level_nodes (line 1034) | def test_works_with_multiple_top_level_nodes(self):
method test_inverted_works_with_multiple_top_level_nodes_with_merge (line 1151) | def test_inverted_works_with_multiple_top_level_nodes_with_merge(self):
method test_inverted_works_with_one_top_level_node (line 1302) | def test_inverted_works_with_one_top_level_node(self):
method test_works_with_split_threads (line 1408) | def test_works_with_split_threads(self):
method test_inverted_works_with_split_threads (line 1525) | def test_inverted_works_with_split_threads(self):
method test_works_with_merged_threads (line 1642) | def test_works_with_merged_threads(self):
method test_inverted_works_with_merged_threads (line 1727) | def test_inverted_works_with_merged_threads(self):
method test_drops_cpython_frames (line 1812) | def test_drops_cpython_frames(self):
method test_inverted_drops_cpython_frames (line 1878) | def test_inverted_drops_cpython_frames(self):
method test_very_deep_call_is_limited (line 1944) | def test_very_deep_call_is_limited(self):
method test_inverted_very_deep_call_is_limited (line 1990) | def test_inverted_very_deep_call_is_limited(self):
method test_single_importlib_frame_is_detected (line 2042) | def test_single_importlib_frame_is_detected(self):
method test_inverted_single_importlib_frame_is_detected (line 2090) | def test_inverted_single_importlib_frame_is_detected(self):
method test_importlib_full_stack_is_detected (line 2149) | def test_importlib_full_stack_is_detected(self):
method test_inverted_importlib_full_stack_is_detected (line 2221) | def test_inverted_importlib_full_stack_is_detected(self):
method test_importlib_partial_stack_is_detected (line 2308) | def test_importlib_partial_stack_is_detected(self):
method test_inverted_importlib_partial_stack_is_detected (line 2396) | def test_inverted_importlib_partial_stack_is_detected(self):
method test_two_branches_first_is_importlib (line 2521) | def test_two_branches_first_is_importlib(self):
method test_inverted_two_branches_first_is_importlib (line 2627) | def test_inverted_two_branches_first_is_importlib(self):
method test_two_branches_second_is_importlib (line 2798) | def test_two_branches_second_is_importlib(self):
method test_inverted_two_branches_second_is_importlib (line 2904) | def test_inverted_two_branches_second_is_importlib(self):
method test_two_branches_both_are_importlib (line 3075) | def test_two_branches_both_are_importlib(self):
method test_inverted_two_branches_both_are_importlib (line 3181) | def test_inverted_two_branches_both_are_importlib(self):
FILE: tests/unit/test_frame_tools.py
class TestFrameFiltering (line 8) | class TestFrameFiltering:
method test_cpython_internal_calls (line 62) | def test_cpython_internal_calls(self, frame, expected):
method test_frame_interesting (line 106) | def test_frame_interesting(self, frame, expected):
method test_is_frame_from_import_system (line 135) | def test_is_frame_from_import_system(self, frame, expected):
FILE: tests/unit/test_high_water_mark_aggregator.py
class Contribution (line 16) | class Contribution:
class Location (line 24) | class Location:
function contribution_by_location_and_allocator (line 31) | def contribution_by_location_and_allocator(allocations):
function test_no_allocations_at_start (line 44) | def test_no_allocations_at_start():
function test_one_allocation_is_both_high_water_mark_and_leaked (line 56) | def test_one_allocation_is_both_high_water_mark_and_leaked():
function test_one_freed_allocation_is_high_water_mark_but_not_leaked (line 77) | def test_one_freed_allocation_is_high_water_mark_but_not_leaked():
function test_zero_byte_allocation (line 101) | def test_zero_byte_allocation():
function test_freeing_one_of_two_high_water_mark_allocations_at_the_same_location (line 123) | def test_freeing_one_of_two_high_water_mark_allocations_at_the_same_loca...
function test_freeing_one_of_two_high_water_mark_allocations_at_different_locations (line 148) | def test_freeing_one_of_two_high_water_mark_allocations_at_different_loc...
function test_allocation_freed_before_high_water_mark (line 180) | def test_allocation_freed_before_high_water_mark():
function test_allocation_made_and_leaked_after_high_water_mark (line 205) | def test_allocation_made_and_leaked_after_high_water_mark():
function test_allocation_made_and_freed_after_high_water_mark (line 237) | def test_allocation_made_and_freed_after_high_water_mark():
function test_allocation_made_and_freed_between_high_water_marks (line 271) | def test_allocation_made_and_freed_between_high_water_marks():
function test_allocation_made_between_high_water_marks_and_freed_after_high_water_mark (line 309) | def test_allocation_made_between_high_water_marks_and_freed_after_high_w...
function test_allocation_made_between_high_water_marks_and_leaked (line 348) | def test_allocation_made_between_high_water_marks_and_leaked():
function test_different_allocators_at_one_location (line 381) | def test_different_allocators_at_one_location():
function test_same_stack_in_different_threads (line 407) | def test_same_stack_in_different_threads():
function test_completely_freed_range (line 439) | def test_completely_freed_range():
function test_shrunk_range (line 463) | def test_shrunk_range():
function test_shrunk_then_freed_range (line 487) | def test_shrunk_then_freed_range():
function test_split_range (line 514) | def test_split_range():
function test_split_then_freed_range (line 538) | def test_split_then_freed_range():
function test_reporting_on_true_high_water_mark_that_was_in_a_past_snapshot (line 565) | def test_reporting_on_true_high_water_mark_that_was_in_a_past_snapshot():
function test_one_allocation_before_first_snapshot (line 609) | def test_one_allocation_before_first_snapshot():
function test_one_allocation_after_first_snapshot (line 632) | def test_one_allocation_after_first_snapshot():
function test_one_allocation_freed_at_high_water_mark_in_second_snapshot (line 656) | def test_one_allocation_freed_at_high_water_mark_in_second_snapshot():
function test_two_allocations_in_different_snapshots (line 682) | def test_two_allocations_in_different_snapshots():
function test_one_allocation_freed_before_high_water_mark_in_second_snapshot (line 720) | def test_one_allocation_freed_before_high_water_mark_in_second_snapshot():
function test_allocations_freed_over_two_snapshots (line 760) | def test_allocations_freed_over_two_snapshots():
function test_allocations_freed_over_two_non_adjacent_snapshots (line 792) | def test_allocations_freed_over_two_non_adjacent_snapshots():
function test_allocation_after_high_water_mark_in_current_snapshot (line 826) | def test_allocation_after_high_water_mark_in_current_snapshot():
function test_allocation_after_high_water_mark_in_historical_snapshot (line 853) | def test_allocation_after_high_water_mark_in_historical_snapshot():
function test_allocation_and_deallocation_after_high_water_mark (line 881) | def test_allocation_and_deallocation_after_high_water_mark():
function test_allocation_and_deal
Condensed preview — 399 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,763K chars).
[
{
"path": ".babelrc",
"chars": 39,
"preview": "{\n \"presets\": [\"@babel/preset-env\"]\n}\n"
},
{
"path": ".bumpversion.cfg",
"chars": 177,
"preview": "[bumpversion]\ncurrent_version = 1.19.2\ncommit = True\nmessage = \n\tPrepare for {new_version} release\n\t\n\tSee changelog for "
},
{
"path": ".clang-format",
"chars": 2801,
"preview": "BasedOnStyle: LLVM\nLanguage: Cpp\nAccessModifierOffset: -2\nAlignAfterOpenBracket: AlwaysBreak\nAlignConsecutiveAssignments"
},
{
"path": ".devcontainer/devcontainer.json",
"chars": 228,
"preview": "{\n \"name\": \"Memray development\",\n \"build\": {\n \"context\": \"..\",\n \"dockerfile\": \"../Dockerfile\"\n },\n \"runArgs\": "
},
{
"path": ".devcontainer/tutorials/devcontainer.json",
"chars": 558,
"preview": "{\n \"name\": \"Memray tutorials\",\n \"build\": {\n \"context\": \"../../docs/tutorials\",\n \"dockerfile\": \"../../docs/tutori"
},
{
"path": ".github/ISSUE_TEMPLATE/---bug-report.yaml",
"chars": 2161,
"preview": "name: 🐞 Bug Report\ndescription: If something isn't working as expected\nlabels: [bug]\nbody:\n - type: checkboxes\n attr"
},
{
"path": ".github/ISSUE_TEMPLATE/---feature-request.yaml",
"chars": 1152,
"preview": "name: 🚀 Feature Request\ndescription: Suggest an idea for this project\nlabels: [enhancement]\n\nbody:\n - type: checkboxes\n"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 185,
"preview": "blank_issues_enabled: true\ncontact_links:\n - name: Long question or idea\n url: https://github.com/bloomberg/memray/d"
},
{
"path": ".github/dependabot.yml",
"chars": 117,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"github-actions\"\n directory: \"/\"\n schedule:\n interval: \"daily\"\n"
},
{
"path": ".github/workflows/build.yml",
"chars": 4133,
"preview": "name: Tests\n\non:\n push:\n branches:\n - main\n pull_request:\n branches:\n - main\n\nconcurrency:\n group: ${"
},
{
"path": ".github/workflows/build_wheels.yml",
"chars": 5975,
"preview": "name: Wheels\n\non:\n push:\n pull_request:\n release:\n types:\n - published\n schedule:\n # At 12:00 on every da"
},
{
"path": ".github/workflows/coverage.yml",
"chars": 2121,
"preview": "name: Coverage\n\npermissions:\n pull-requests: write\n\non:\n push:\n branches:\n - main\n pull_request:\n branches"
},
{
"path": ".github/workflows/docs.yml",
"chars": 1026,
"preview": "name: Docs\n\non:\n push:\n branches:\n - main\n\njobs:\n publish_docs:\n name: Publish docs\n runs-on: ubuntu-lat"
},
{
"path": ".github/workflows/news-check.yml",
"chars": 626,
"preview": "name: News entry check\non:\n pull_request:\n paths:\n - \"src/memray/**\"\n types:\n - \"opened\"\n - \"reope"
},
{
"path": ".github/workflows/sanity-check.yml",
"chars": 539,
"preview": "name: Sanity check\non:\n pull_request:\n types:\n - \"opened\"\n - \"reopened\"\n - \"synchronize\"\n - \"lab"
},
{
"path": ".github/workflows/test_uv_python.yml",
"chars": 1326,
"preview": "name: UV Python Tests\n\non:\n push:\n branches:\n - main\n pull_request:\n branches:\n - main\n\nconcurrency:\n "
},
{
"path": ".gitignore",
"chars": 2516,
"preview": "# IDE stuff\n\n.idea/*\n\n# Cmake stuff\n\nCMakeLists.txt.user\nCMakeCache.txt\nCMakeFiles\nCMakeScripts\nTesting\nMakefile\ncmake_i"
},
{
"path": ".pre-commit-config.yaml",
"chars": 1718,
"preview": "exclude: \"^(src/memray/reporters/templates/assets|src/vendor|benchmarks|docs/_static/flamegraphs)/\"\nrepos:\n - repo: htt"
},
{
"path": "CONTRIBUTING.md",
"chars": 5408,
"preview": "# Contributing\n\nBefore contributing to this repository, first please discuss the change you wish to make via an\nissue, o"
},
{
"path": "Dockerfile",
"chars": 1105,
"preview": "FROM debian:bookworm-slim\n\nARG DEBIAN_FRONTEND=noninteractive\n\nRUN apt-get update \\\n && apt-get install -y --force-ye"
},
{
"path": "LICENSE",
"chars": 11343,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "MANIFEST.in",
"chars": 1054,
"preview": "exclude .clang-format\nexclude asv.conf.json\nexclude CONTRIBUTING.md\nexclude Dockerfile\nexclude Jenkinsfile\nexclude requi"
},
{
"path": "NEWS.rst",
"chars": 27947,
"preview": ".. note\n You should *NOT* add new change log entries to this file, this\n file is managed by towncrier. You *may* e"
},
{
"path": "README.md",
"chars": 17136,
"preview": "<p align=\"center\">\n<img src=\"https://raw.githubusercontent.com/bloomberg/memray/main/docs/_static/images/logo.png\" width"
},
{
"path": "asv.conf.json",
"chars": 6855,
"preview": "{\n // The version of the config file format. Do not change, unless\n // you know what you are doing.\n \"version\""
},
{
"path": "benchmarks/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "benchmarks/benchmarking/__main__.py",
"chars": 6028,
"preview": "import dataclasses\nimport json\nimport pathlib\nimport subprocess\nimport sys\nimport tempfile\nfrom typing import List\n\nfrom"
},
{
"path": "benchmarks/benchmarking/cases/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "benchmarks/benchmarking/cases/async_tree_base.py",
"chars": 4113,
"preview": "\"\"\"\nBenchmark for async tree workload, which calls asyncio.gather() on a tree\n(6 levels deep, 6 branches per level) with"
},
{
"path": "benchmarks/benchmarking/cases/async_tree_memray.py",
"chars": 4325,
"preview": "\"\"\"\nBenchmark for async tree workload, which calls asyncio.gather() on a tree\n(6 levels deep, 6 branches per level) with"
},
{
"path": "benchmarks/benchmarking/cases/deltablue_base.py",
"chars": 17016,
"preview": "\"\"\"\ndeltablue.py\n============\n\nPorted for the PyPy project.\nContributed by Daniel Lindsley\n\nThis implementation of the D"
},
{
"path": "benchmarks/benchmarking/cases/deltablue_memray.py",
"chars": 17353,
"preview": "\"\"\"\ndeltablue.py\n============\n\nPorted for the PyPy project.\nContributed by Daniel Lindsley\n\nThis implementation of the D"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/api/publisher.txt",
"chars": 10569,
"preview": "========================\n The Docutils Publisher\n========================\n\n:Author: David Goodger\n:Contact: docutils-dev"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/api/runtime-settings.txt",
"chars": 6215,
"preview": "===========================\n Docutils Runtime Settings\n===========================\n\n:Author: David Goodger, Günter Milde"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/api/transforms.txt",
"chars": 6334,
"preview": "=====================\n Docutils Transforms\n=====================\n\n:Author: David Goodger\n:Contact: docutils-develop@list"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/distributing.txt",
"chars": 4530,
"preview": "===============================\n Docutils_ Distributor's Guide\n===============================\n\n:Author: Lea Wiemann\n:Co"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/enthought-plan.txt",
"chars": 16986,
"preview": "===========================================\n Plan for Enthought API Documentation Tool\n================================="
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/enthought-rfp.txt",
"chars": 4531,
"preview": "==================================\n Enthought API Documentation Tool\n==================================\n----------------"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/hacking.txt",
"chars": 9172,
"preview": "==========================\n Docutils_ Hacker's Guide\n==========================\n\n:Author: Lea Wiemann\n:Contact: docutils"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/policies.txt",
"chars": 25778,
"preview": "===========================\n Docutils Project Policies\n===========================\n\n:Author: David Goodger; open to all "
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/pysource.txt",
"chars": 4380,
"preview": "======================\n Python Source Reader\n======================\n:Author: David Goodger\n:Contact: docutils-develop@li"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/release.txt",
"chars": 3497,
"preview": "=============================\n Docutils_ Release Procedure\n=============================\n\n:Authors: David Goodger; Lea W"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/repository.txt",
"chars": 9439,
"preview": "=====================================\n The Docutils_ Version Repository\n=====================================\n\n:Author: "
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/rst/alternatives.txt",
"chars": 113255,
"preview": "==================================================\n A Record of reStructuredText Syntax Alternatives\n==================="
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/rst/problems.txt",
"chars": 35463,
"preview": "==============================\n Problems With StructuredText\n==============================\n:Author: David Goodger\n:Cont"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/runtime-settings-processing.txt",
"chars": 10643,
"preview": "=============================\n Runtime Settings Processing\n=============================\n\n:Author: David Goodger, Günter"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/semantics.txt",
"chars": 4511,
"preview": "=====================\n Docstring Semantics\n=====================\n:Author: David Goodger\n:Contact: docutils-develop@lists"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/testing.txt",
"chars": 9503,
"preview": "===================\n Docutils_ Testing\n===================\n\n:Authors: Lea Wiemann <LeWiemann@gmail.com>;\n David"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/todo.txt",
"chars": 98576,
"preview": "======================\n Docutils_ To Do List\n======================\n\n:Author: David Goodger (with input from many); open"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/dev/website.txt",
"chars": 3274,
"preview": "===================\n Docutils Web Site\n===================\n\n:Author: David Goodger; open to all Docutils developers\n:Con"
},
{
"path": "benchmarks/benchmarking/cases/docutils_data/docs/index.txt",
"chars": 8264,
"preview": "==========================================\n Docutils Project Documentation Overview\n===================================="
},
{
"path": "benchmarks/benchmarking/cases/docutils_html_base.py",
"chars": 1508,
"preview": "\"\"\"\nConvert Docutils' documentation from reStructuredText to <format>.\n\"\"\"\n\nimport contextlib\nfrom pathlib import Path\ni"
},
{
"path": "benchmarks/benchmarking/cases/docutils_html_memray.py",
"chars": 1764,
"preview": "\"\"\"\nConvert Docutils' documentation from reStructuredText to <format>.\n\"\"\"\n\nimport contextlib\nfrom pathlib import Path\n\n"
},
{
"path": "benchmarks/benchmarking/cases/fannkuch_base.py",
"chars": 1086,
"preview": "\"\"\"\nThe Computer Language Benchmarks Game\nhttp://benchmarksgame.alioth.debian.org/\n\nContributed by Sokolov Yura, modifie"
},
{
"path": "benchmarks/benchmarking/cases/fannkuch_memray.py",
"chars": 1229,
"preview": "\"\"\"\nThe Computer Language Benchmarks Game\nhttp://benchmarksgame.alioth.debian.org/\n\nContributed by Sokolov Yura, modifie"
},
{
"path": "benchmarks/benchmarking/cases/go_base.py",
"chars": 14052,
"preview": "\"\"\"\nGo board game\n\"\"\"\nimport math\nimport random\n\nSIZE = 9\nGAMES = 200\nKOMI = 7.5\nEMPTY, WHITE, BLACK = 0, 1, 2\nSHOW = {E"
},
{
"path": "benchmarks/benchmarking/cases/go_memray.py",
"chars": 14375,
"preview": "\"\"\"\nGo board game\n\"\"\"\nimport math\nimport random\n\nimport pyperf\nfrom memray_helper import get_tracker\n\n\nSIZE = 9\nGAMES = "
},
{
"path": "benchmarks/benchmarking/cases/hexion_base.py",
"chars": 16687,
"preview": "\"\"\"\nSolver of Hexiom board game.\n\nBenchmark from Laurent Vaucher.\n\nSource: https://github.com/slowfrog/hexiom : hexiom2."
},
{
"path": "benchmarks/benchmarking/cases/hexion_memray.py",
"chars": 17523,
"preview": "\"\"\"\nSolver of Hexiom board game.\n\nBenchmark from Laurent Vaucher.\n\nSource: https://github.com/slowfrog/hexiom : hexiom2."
},
{
"path": "benchmarks/benchmarking/cases/json_dumps_base.py",
"chars": 862,
"preview": "import json\nimport sys\n\n\nEMPTY = ({}, 2000)\nSIMPLE_DATA = {\n \"key1\": 0,\n \"key2\": True,\n \"key3\": \"value\",\n \"k"
},
{
"path": "benchmarks/benchmarking/cases/json_dumps_memray.py",
"chars": 1616,
"preview": "import json\nimport sys\n\nimport pyperf\nfrom memray_helper import get_tracker\n\n\nEMPTY = ({}, 2000)\nSIMPLE_DATA = {\n \"ke"
},
{
"path": "benchmarks/benchmarking/cases/json_loads_base.py",
"chars": 2858,
"preview": "\"\"\"Script for testing the performance of json parsing and serialization.\n\nThis will dump/load several real world-represe"
},
{
"path": "benchmarks/benchmarking/cases/json_loads_memray.py",
"chars": 3325,
"preview": "\"\"\"Script for testing the performance of json parsing and serialization.\n\nThis will dump/load several real world-represe"
},
{
"path": "benchmarks/benchmarking/cases/mdp_base.py",
"chars": 8515,
"preview": "import collections\nfrom collections import defaultdict\nfrom fractions import Fraction\n\n\ndef topoSort(roots, getParents):"
},
{
"path": "benchmarks/benchmarking/cases/mdp_memray.py",
"chars": 8748,
"preview": "import collections\nfrom collections import defaultdict\nfrom fractions import Fraction\nfrom memray_helper import get_trac"
},
{
"path": "benchmarks/benchmarking/cases/meteor_context_base.py",
"chars": 7933,
"preview": "\"\"\"\nMeteor Puzzle board:\nhttp://benchmarksgame.alioth.debian.org/u32/meteor-description.html#meteor\n\nThe Computer Langua"
},
{
"path": "benchmarks/benchmarking/cases/meteor_context_memray.py",
"chars": 8263,
"preview": "\"\"\"\nMeteor Puzzle board:\nhttp://benchmarksgame.alioth.debian.org/u32/meteor-description.html#meteor\n\nThe Computer Langua"
},
{
"path": "benchmarks/benchmarking/cases/nbody_base.py",
"chars": 4161,
"preview": "\"\"\"\nN-body benchmark from the Computer Language Benchmarks Game.\n\nThis is intended to support Unladen Swallow's pyperf.p"
},
{
"path": "benchmarks/benchmarking/cases/nbody_memray.py",
"chars": 4864,
"preview": "\"\"\"\nN-body benchmark from the Computer Language Benchmarks Game.\n\nThis is intended to support Unladen Swallow's pyperf.p"
},
{
"path": "benchmarks/benchmarking/cases/nqueens_base.py",
"chars": 1749,
"preview": "\"\"\"Simple, brute-force N-Queens solver.\"\"\"\n\n__author__ = \"collinwinter@google.com (Collin Winter)\"\n\n\n# Pure-Python imple"
},
{
"path": "benchmarks/benchmarking/cases/nqueens_memray.py",
"chars": 1952,
"preview": "\"\"\"Simple, brute-force N-Queens solver.\"\"\"\n\nimport pyperf\nfrom memray_helper import get_tracker\n\n__author__ = \"collinwin"
},
{
"path": "benchmarks/benchmarking/cases/pickles_base.py",
"chars": 7208,
"preview": "\"\"\"Script for testing the performance of pickling/unpickling.\n\nThis will pickle/unpickle several real world-representati"
},
{
"path": "benchmarks/benchmarking/cases/pickles_memray.py",
"chars": 8866,
"preview": "\"\"\"Script for testing the performance of pickling/unpickling.\n\nThis will pickle/unpickle several real world-representati"
},
{
"path": "benchmarks/benchmarking/cases/pprint_format_base.py",
"chars": 487,
"preview": "\"\"\"Test the performance of pprint.PrettyPrinter.\n\nThis benchmark was available as `python -m pprint` until Python 3.12.\n"
},
{
"path": "benchmarks/benchmarking/cases/pprint_format_memray.py",
"chars": 839,
"preview": "\"\"\"Test the performance of pprint.PrettyPrinter.\n\nThis benchmark was available as `python -m pprint` until Python 3.12.\n"
},
{
"path": "benchmarks/benchmarking/cases/raytrace_base.py",
"chars": 11094,
"preview": "\"\"\"\nThis file contains definitions for a simple raytracer.\nCopyright Callum and Tony Garnock-Jones, 2008.\n\nThis file may"
},
{
"path": "benchmarks/benchmarking/cases/raytrace_memray.py",
"chars": 12074,
"preview": "\"\"\"\nThis file contains definitions for a simple raytracer.\nCopyright Callum and Tony Garnock-Jones, 2008.\n\nThis file may"
},
{
"path": "benchmarks/benchmarking/cases/regex_dna_base.py",
"chars": 5387,
"preview": "#!/usr/bin/env python\n\"\"\"\nThe Computer Language Benchmarks Game\nhttp://benchmarksgame.alioth.debian.org/\n\nregex-dna Pyth"
},
{
"path": "benchmarks/benchmarking/cases/regex_dna_memray.py",
"chars": 6740,
"preview": "#!/usr/bin/env python\n\"\"\"\nThe Computer Language Benchmarks Game\nhttp://benchmarksgame.alioth.debian.org/\n\nregex-dna Pyth"
},
{
"path": "benchmarks/benchmarking/cases/regex_effbot_base.py",
"chars": 4677,
"preview": "\"\"\"Benchmarks for Python's regex engine.\n\nThese are some of the original benchmarks used to tune Python's regex engine\ni"
},
{
"path": "benchmarks/benchmarking/cases/regex_effbot_memray.py",
"chars": 5387,
"preview": "\"\"\"Benchmarks for Python's regex engine.\n\nThese are some of the original benchmarks used to tune Python's regex engine\ni"
},
{
"path": "benchmarks/benchmarking/cases/regex_v8_base.py",
"chars": 126726,
"preview": "# Copyright 2009 the V8 project authors. All rights reserved.\n# Redistribution and use in source and binary forms, with "
},
{
"path": "benchmarks/benchmarking/cases/regex_v8_memray.py",
"chars": 127063,
"preview": "# Copyright 2009 the V8 project authors. All rights reserved.\n# Redistribution and use in source and binary forms, with "
},
{
"path": "benchmarks/benchmarking/cases/spectral_norm_base.py",
"chars": 1458,
"preview": "\"\"\"\nMathWorld: \"Hundred-Dollar, Hundred-Digit Challenge Problems\", Challenge #3.\nhttp://mathworld.wolfram.com/Hundred-Do"
},
{
"path": "benchmarks/benchmarking/cases/spectral_norm_memray.py",
"chars": 1817,
"preview": "\"\"\"\nMathWorld: \"Hundred-Dollar, Hundred-Digit Challenge Problems\", Challenge #3.\nhttp://mathworld.wolfram.com/Hundred-Do"
},
{
"path": "benchmarks/benchmarking/cases/sqlite_synth_base.py",
"chars": 1187,
"preview": "\"\"\"\nSQLite benchmark.\n\nThe goal of the benchmark is to test CFFI performance and going back and forth\nbetween SQLite and"
},
{
"path": "benchmarks/benchmarking/cases/sqlite_synth_memray.py",
"chars": 1495,
"preview": "\"\"\"\nSQLite benchmark.\n\nThe goal of the benchmark is to test CFFI performance and going back and forth\nbetween SQLite and"
},
{
"path": "benchmarks/benchmarking/cases/telco_base.py",
"chars": 2875,
"preview": "# coding: UTF-8\n\"\"\" Telco Benchmark for measuring the performance of decimal calculations\n\n- http://speleotrove.com/deci"
},
{
"path": "benchmarks/benchmarking/cases/telco_memray.py",
"chars": 3436,
"preview": "# coding: UTF-8\n\"\"\" Telco Benchmark for measuring the performance of decimal calculations\n\n- http://speleotrove.com/deci"
},
{
"path": "benchmarks/benchmarking/plot.py",
"chars": 2924,
"preview": "from pathlib import Path\nfrom typing import Any\nfrom typing import Dict\n\nimport matplotlib\nimport matplotlib.patches as "
},
{
"path": "benchmarks/benchmarks.py",
"chars": 8253,
"preview": "import mmap\nimport os\nimport tempfile\n\nfrom memray import AllocatorType\nfrom memray import FileReader\n\ntry:\n from mem"
},
{
"path": "benchmarks/requirements.txt",
"chars": 32,
"preview": "pyperf\nmatplotlib\nseaborn\nnumpy\n"
},
{
"path": "docs/_static/css/custom.css",
"chars": 7297,
"preview": "/* GLOBAL STYLES\n-------------------------------------------------- */\n/* Padding below the footer and lighter body text"
},
{
"path": "docs/_static/flamegraphs/.gitattributes",
"chars": 13,
"preview": "*.html -diff\n"
},
{
"path": "docs/_static/js/custom.js",
"chars": 610,
"preview": "function reveal() {\n var classes = [\".reveal_l\", \".reveal_r\"];\n classes.map(function (c) {\n var reveals = document."
},
{
"path": "docs/_templates/index.html",
"chars": 22097,
"preview": "<!doctype html>\n<html lang=\"en\">\n\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-widt"
},
{
"path": "docs/api.rst",
"chars": 2866,
"preview": ".. module:: memray\n\nMemray API\n==========\n\nMemray exposes an API that can be used to programmatically activate or\ndeacti"
},
{
"path": "docs/attach.rst",
"chars": 6298,
"preview": "Attaching to a running process\n==============================\n\nMemray allows you to attach to a running process and to o"
},
{
"path": "docs/conf.py",
"chars": 3067,
"preview": "\"\"\"Sphinx configuration file for memray's documentation.\"\"\"\n\nimport os\n\nimport memray.commands\n\n# -- General configurati"
},
{
"path": "docs/examples/README.rst",
"chars": 1543,
"preview": ".. _example-applications:\n\nExample Applications for Memray\n=================================\n\nThe projects in the direct"
},
{
"path": "docs/examples/fibonacci/fib.py",
"chars": 415,
"preview": "import sys\n\n\ndef fib1(n):\n my_list = [0, 1]\n for i in range(2, n + 1):\n my_list.append(my_list[i - 1] + my_"
},
{
"path": "docs/examples/mandelbrot/mandelbrot-threaded.py",
"chars": 1432,
"preview": "from threading import Thread\n\nimport numpy as np\n\n\ndef mandelbrot(height, width, x=-0.5, y=0, zoom=1, max_iterations=100"
},
{
"path": "docs/examples/mandelbrot/mandelbrot.py",
"chars": 1210,
"preview": "import numpy as np\n\n\ndef mandelbrot(height, width, x=-0.5, y=0, zoom=1, max_iterations=100):\n # To make navigation ea"
},
{
"path": "docs/examples/mandelbrot/requirements.txt",
"chars": 6,
"preview": "numpy\n"
},
{
"path": "docs/examples/nbody/example.py",
"chars": 4048,
"preview": "\"\"\"\nIn this example we investigate the primordial Earth embedded in a disk of\nplanetesimals, integrating it for a short "
},
{
"path": "docs/examples/nbody/requirements.txt",
"chars": 14,
"preview": "numpy\nrebound\n"
},
{
"path": "docs/examples/sqlite/example.py",
"chars": 1465,
"preview": "import random\nimport sqlite3\nimport string\nimport time\n\ncreate_statement = \"\"\"\nCREATE TABLE IF NOT EXISTS database_threa"
},
{
"path": "docs/flamegraph.rst",
"chars": 17823,
"preview": "Flame Graph Reporter\n====================\n\nThe flame graph reporter generates an HTML file containing a flame graph\nrepr"
},
{
"path": "docs/getting_started.rst",
"chars": 3415,
"preview": "Getting started\n===============\n\nInstallation\n------------\n\nMemray can easily be installed from PyPI.\n\nPyPI\n~~~~\n\nWhen i"
},
{
"path": "docs/index.rst",
"chars": 640,
"preview": ".. toctree::\n :hidden:\n\n overview\n getting_started\n\n.. toctree::\n :hidden:\n :caption: Hands-on Tutorial\n\n tu"
},
{
"path": "docs/jupyter_magic.rst",
"chars": 1173,
"preview": ".. _Jupyter integration:\n\nJupyter Integration\n===================\n\nWe provide an IPython extension that adds a new Jupyt"
},
{
"path": "docs/licenses.rst",
"chars": 24462,
"preview": "Licenses\n========\n\nMemray utilizes several other open source libraries under the hood. These are\nthe licenses of those l"
},
{
"path": "docs/live.rst",
"chars": 5135,
"preview": "Live Reporting\n==============\n\nOverview\n--------\n\nMemray supports presenting a \"live\" view for observing the heap memory"
},
{
"path": "docs/manpage.rst",
"chars": 2834,
"preview": ":orphan:\n\nOverview\n========\n\n.. argparse::\n :ref: memray.commands.get_argument_parser\n :manpage:\n :nosubcommands:\n"
},
{
"path": "docs/memory.rst",
"chars": 8431,
"preview": ".. _memory overview:\n\nMemory overview\n===============\n\nHeap memory vs resident memory\n------------------------------\n\nWh"
},
{
"path": "docs/native_mode.rst",
"chars": 10494,
"preview": "Symbolic information in native mode\n===================================\n\n.. highlight:: shell-session\n\n.. important::\n\n "
},
{
"path": "docs/overview.rst",
"chars": 1419,
"preview": "Overview\n--------\n\n.. image:: _static/images/logo.png\n\n.. image:: _static/images/output.png\n\nMemray is a memory profiler"
},
{
"path": "docs/performance.rst",
"chars": 4271,
"preview": "Performance\n===========\n\nThis section contains an analysis of the overhead of running Memray over different\ntest cases a"
},
{
"path": "docs/python_allocators.rst",
"chars": 6509,
"preview": ".. _Python allocators:\n\nPython allocators\n=================\n\nPython has a layer of abstraction between code that allocat"
},
{
"path": "docs/run.rst",
"chars": 11964,
"preview": "The ``run`` subcommand\n======================\n\nThe ``run`` subcommand is used to launch a new Python process and track t"
},
{
"path": "docs/stats.rst",
"chars": 1873,
"preview": "Stats Reporter\n==============\n\nThe stats reporter generates high level statistics about the tracked process's\nmemory all"
},
{
"path": "docs/summary.rst",
"chars": 1149,
"preview": "Summary Reporter\n================\n\nThe summary reporter provides a quick overview of allocated memory at the time\nwhen t"
},
{
"path": "docs/supported_environments.rst",
"chars": 3206,
"preview": "Supported environments\n======================\n\nSupported Python interpreters\n-----------------------------\n\nOnly CPython"
},
{
"path": "docs/table.rst",
"chars": 1433,
"preview": "Table Reporter\n==============\n\nThe table reporter generates an HTML document showing a simple tabular view of\nthe alloca"
},
{
"path": "docs/temporary_allocations.rst",
"chars": 4401,
"preview": "Temporary allocations\n=====================\n\nSome reporters accept the ``--temporary-allocation-threshold=THRESHOLD`` an"
},
{
"path": "docs/transform.rst",
"chars": 3962,
"preview": "Transform Reporter\n==================\n\nThe transform reporter is used to convert a Memray capture file into a format\ntha"
},
{
"path": "docs/tree.rst",
"chars": 2614,
"preview": "Tree Reporter\n==============\n\nThe tree reporter provides a simplified representation of the call hierarchy of\nthe tracke"
},
{
"path": "docs/tutorials/1.rst",
"chars": 12143,
"preview": "Exercise 1 - Fibonacci Sequence\n===============================\n\nIntro\n---------\n\nThis first lesson is meant to familiar"
},
{
"path": "docs/tutorials/2.rst",
"chars": 4809,
"preview": "Exercise 2 - Clinging Onto Memory\n=================================\n\nIntro\n-----\n\nUnlike some low level languages like C"
},
{
"path": "docs/tutorials/3.rst",
"chars": 8406,
"preview": "Exercise 3 - LRU Cache\n======================\n\nIntro\n-----\n\nIn :doc:`exercise 2 <2>` we experimented with how and when P"
},
{
"path": "docs/tutorials/Dockerfile",
"chars": 611,
"preview": "FROM debian:bookworm-slim\n\nARG DEBIAN_FRONTEND=noninteractive\n\nRUN apt-get update \\\n && apt-get install -y --force-ye"
},
{
"path": "docs/tutorials/additional_features.rst",
"chars": 1922,
"preview": "What to learn about next\n========================\n\nWe've now acquainted ourselves with Memray, and had a look at how it "
},
{
"path": "docs/tutorials/exercise_1/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs/tutorials/exercise_1/fibonacci.py",
"chars": 1090,
"preview": "import operator\nfrom functools import reduce\nfrom itertools import chain\n\n\ndef fibonacci(length):\n # edge cases\n i"
},
{
"path": "docs/tutorials/exercise_2/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs/tutorials/exercise_2/holding_onto_memory.py",
"chars": 974,
"preview": "import numpy as np\n\n# DO NOT CHANGE\nMB_CONVERSION = 1000 * 1000\nDUPLICATE_CONST = 2\n\nSIZE_OF_DATA_IN_MB = 100\nSUBTRACT_A"
},
{
"path": "docs/tutorials/exercise_3/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs/tutorials/exercise_3/lru_cache.py",
"chars": 1088,
"preview": "# pylint: disable=C0114 C0115 C0116 R0903 C0103\n\nimport functools\nfrom collections import Counter\n\n# DO NOT CHANGE\nFIRST"
},
{
"path": "docs/tutorials/index.rst",
"chars": 724,
"preview": "About This Tutorial\n===================\n\nThe tutorials in this section of the docs provide a gentle introduction to debu"
},
{
"path": "docs/tutorials/requirements-tutorial.txt",
"chars": 41,
"preview": "memray\nnumpy\npylint\npytest\npytest-memray\n"
},
{
"path": "docs/tutorials/solutions/exercise_1/fibonacci.py",
"chars": 1083,
"preview": "import operator\nfrom functools import reduce\nfrom itertools import chain\n\n\ndef fibonacci(length):\n # edge cases\n i"
},
{
"path": "docs/tutorials/solutions/exercise_2/holding_onto_memory.py",
"chars": 1488,
"preview": "import numpy as np\n\n# DO NOT CHANGE\nMB_CONVERSION = 1024 * 1024\nDUPLICATE_CONST = 2\n\nSIZE_OF_DATA_IN_MB = 100\nSUBTRACT_A"
},
{
"path": "docs/tutorials/solutions/exercise_3/lru_cache.py",
"chars": 1079,
"preview": "import functools\nfrom collections import Counter\n\n# DO NOT CHANGE\nFIRST_COUNTER_RANGE = 500\nSECOND_COUNTER_RANGE = 1000\n"
},
{
"path": "docs/tutorials/tests/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "docs/tutorials/tests/test_exercise_1.py",
"chars": 1346,
"preview": "import pytest\nfrom exercise_1.fibonacci import generate_fibonacci_hash\n\n# Memory tests\n\n\n@pytest.mark.limit_memory(\"100 "
},
{
"path": "docs/tutorials/tests/test_exercise_2.py",
"chars": 257,
"preview": "import numpy as np\nimport pytest\nfrom exercise_2.holding_onto_memory import process_data\n\n\n@pytest.mark.limit_memory(\"23"
},
{
"path": "docs/tutorials/tests/test_exercise_3.py",
"chars": 1703,
"preview": "import math\n\nimport pytest\nfrom exercise_3.lru_cache import Algorithms\nfrom exercise_3.lru_cache import compare_counts_d"
},
{
"path": "news/.gitignore",
"chars": 12,
"preview": "!.gitignore\n"
},
{
"path": "package.json",
"chars": 750,
"preview": "{\n \"name\": \"memray\",\n \"private\": true,\n \"devDependencies\": {\n \"@babel/preset-env\": \"^7.14.7\",\n \"copy-webpack-pl"
},
{
"path": "pyproject.toml",
"chars": 4864,
"preview": "[build-system]\n\nrequires = [\n \"setuptools\",\n \"wheel\",\n \"pkgconfig\",\n \"Cython>=0.29.31\"\n]\n\nbuild-backend "
},
{
"path": "requirements-docs.txt",
"chars": 53,
"preview": "IPython\nsphinx\nsphinx-autobuild\nsphinx-argparse\nfuro\n"
},
{
"path": "requirements-extra.txt",
"chars": 64,
"preview": "mypy\nbump2version\ntowncrier\npre-commit\n-r requirements-docs.txt\n"
},
{
"path": "requirements-test.txt",
"chars": 173,
"preview": "Cython\ncoverage[toml]\ngreenlet; python_version < '3.14'\npytest\npytest-cov\nipython\nsetuptools\npkgconfig\npytest-textual-sn"
},
{
"path": "setup.py",
"chars": 11081,
"preview": "import distutils.command.build\nimport distutils.log\nimport os\nimport pathlib\nimport subprocess\nimport sys\nimport tempfil"
},
{
"path": "src/memray/__init__.py",
"chars": 925,
"preview": "from ._ipython import load_ipython_extension\nfrom ._memray import AllocationRecord\nfrom ._memray import AllocatorType\nfr"
},
{
"path": "src/memray/__init__.pyi",
"chars": 652,
"preview": "from memray._destination import Destination as Destination\nfrom memray._destination import FileDestination as FileDestin"
},
{
"path": "src/memray/__main__.py",
"chars": 94,
"preview": "import sys\n\nfrom memray.commands import main\n\nif __name__ == \"__main__\":\n sys.exit(main())\n"
},
{
"path": "src/memray/_destination.py",
"chars": 1814,
"preview": "import pathlib\nimport typing\nfrom dataclasses import dataclass\n\n\n@dataclass(frozen=True)\nclass Destination:\n pass\n\n\n@"
},
{
"path": "src/memray/_errors.py",
"chars": 331,
"preview": "from typing import Any\n\n\nclass MemrayError(Exception):\n \"\"\"Exceptions raised in this package.\"\"\"\n\n\nclass MemrayComman"
},
{
"path": "src/memray/_ipython/__init__.py",
"chars": 206,
"preview": "from typing import Any\n\n\ndef load_ipython_extension(ipython: Any) -> None:\n from .flamegraph import FlamegraphMagics\n"
},
{
"path": "src/memray/_ipython/flamegraph.py",
"chars": 8648,
"preview": "import argparse\nimport shlex\nimport tempfile\nfrom pathlib import Path\nfrom textwrap import dedent\nfrom textwrap import i"
},
{
"path": "src/memray/_memray/CMakeLists.txt",
"chars": 1609,
"preview": "cmake_minimum_required(VERSION 3.10)\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED ON)\nproject(_memray)\n\nfi"
},
{
"path": "src/memray/_memray/__init__.pxd",
"chars": 0,
"preview": ""
},
{
"path": "src/memray/_memray/algorithm.pxd",
"chars": 120,
"preview": "cdef extern from \"<algorithm>\" namespace \"std\" nogil:\n ssize_t count[Iter, T](Iter first, Iter last, const T& value)\n"
},
{
"path": "src/memray/_memray/alloc.h",
"chars": 453,
"preview": "#pragma once\n\n#ifdef __linux__\n# include <malloc.h>\n#endif\n\n#include <stdlib.h>\n\nextern \"C\" {\n#ifndef __GLIBC__\nstati"
},
{
"path": "src/memray/_memray/alloc.pxd",
"chars": 985,
"preview": "cdef extern from \"alloc.h\" nogil:\n void *calloc (size_t count, size_t eltsize)\n void free (void *ptr)\n void *ma"
},
{
"path": "src/memray/_memray/compat.cpp",
"chars": 6789,
"preview": "#include \"compat.h\"\n\nnamespace memray::compat {\n\nvoid\nsetprofileAllThreads(Py_tracefunc func, PyObject* arg)\n{\n asser"
},
{
"path": "src/memray/_memray/compat.h",
"chars": 3779,
"preview": "#pragma once\n\n#define PY_SSIZE_T_CLEAN\n#include <Python.h>\n\n#include \"frameobject.h\"\n#include <cassert>\n#include <string"
},
{
"path": "src/memray/_memray/elf_shenanigans.cpp",
"chars": 7759,
"preview": "#include <cstring>\n#include <set>\n#include <string>\n#include <sys/mman.h>\n#include <unistd.h>\n\n#include \"elf_utils.h\"\n#i"
},
{
"path": "src/memray/_memray/elf_utils.h",
"chars": 9629,
"preview": "#pragma once\n\n#include <cstdint>\n#include <cstring>\n#include <iostream>\n#include <string>\n#include <sys/mman.h>\n#include"
},
{
"path": "src/memray/_memray/exceptions.h",
"chars": 291,
"preview": "#pragma once\n\n#include <stdexcept>\n\nnamespace memray::exception {\n\nclass MemrayException : public std::runtime_error\n{\n "
},
{
"path": "src/memray/_memray/frame_tree.h",
"chars": 2123,
"preview": "#pragma once\n#include <vector>\n\n#include \"records.h\"\n\nnamespace memray::tracking_api {\nclass FrameTree\n{\n public:\n u"
},
{
"path": "src/memray/_memray/hooks.cpp",
"chars": 13498,
"preview": "#include <cassert>\n#include <cstdio>\n#include <mutex>\n#include <unordered_set>\n\n#include \"hooks.h\"\n#include \"tracking_ap"
},
{
"path": "src/memray/_memray/hooks.h",
"chars": 6706,
"preview": "#pragma once\n\n#define PY_SSIZE_T_CLEAN\n#include <Python.h>\n\n#include <sys/mman.h>\n#include <sys/types.h>\n\n#include <cstd"
},
{
"path": "src/memray/_memray/hooks.pxd",
"chars": 215,
"preview": "from _memray.records cimport Allocation\nfrom libcpp cimport bool\n\n\ncdef extern from \"hooks.h\" namespace \"memray::hooks\":"
},
{
"path": "src/memray/_memray/inject.cpp",
"chars": 7018,
"preview": "#include <netdb.h>\n#include <stdint.h>\n#include <sys/socket.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#include <ios"
},
{
"path": "src/memray/_memray/linker_shenanigans.h",
"chars": 517,
"preview": "#pragma once\n\n#include <set>\n#include <string>\n\n#include <dlfcn.h>\n\nnamespace memray::linker {\n\nstatic void\n_dummy(void)"
},
{
"path": "src/memray/_memray/logging.cpp",
"chars": 846,
"preview": "#include <iostream>\n#include <stdexcept>\n\n#include \"logging.h\"\n\nnamespace memray {\n\nstatic int LOG_THRESHOLD = static_ca"
},
{
"path": "src/memray/_memray/logging.h",
"chars": 957,
"preview": "#ifndef _MEMRAY_LOGGING_H\n#define _MEMRAY_LOGGING_H\n\n#include <sstream>\n#include <string>\n\nnamespace memray {\n\nenum logL"
},
{
"path": "src/memray/_memray/logging.pxd",
"chars": 79,
"preview": "cdef extern from \"logging.h\" namespace \"memray\":\n void setLogThreshold(int)\n"
},
{
"path": "src/memray/_memray/lz4_stream.h",
"chars": 9616,
"preview": "// Copyright (c) 2015, Kasper Laudrup <laudrup@stacktrace.dk>\n// All rights reserved.\n//\n// Redistribution and use in so"
},
{
"path": "src/memray/_memray/macho_shenanigans.cpp",
"chars": 18531,
"preview": "#include <cstring>\n\n#include \"hooks.h\"\n#include \"linker_shenanigans.h\"\n#include \"logging.h\"\n#include \"macho_utils.h\"\n#in"
},
{
"path": "src/memray/_memray/macho_utils.h",
"chars": 3759,
"preview": "#pragma once\n\n#include <cstring>\n#include <dlfcn.h>\n#include <mach-o/dyld.h>\n#include <mach-o/loader.h>\n#include <mach-o"
},
{
"path": "src/memray/_memray/native_resolver.cpp",
"chars": 14995,
"preview": "#include <cstring>\n#include <iostream>\n#include <utility>\n\n#include \"native_resolver.h\"\n\n#include \"logging.h\"\n\nnamespace"
},
{
"path": "src/memray/_memray/native_resolver.h",
"chars": 4676,
"preview": "#pragma once\n\n#define PY_SSIZE_T_CLEAN\n#include <Python.h>\n\n#include <algorithm>\n#include <memory>\n#include <string>\n#in"
},
{
"path": "src/memray/_memray/native_resolver.pxd",
"chars": 184,
"preview": "from libcpp.string cimport string\nfrom libcpp.vector cimport vector\n\n\ncdef extern from \"native_resolver.h\" namespace \"me"
},
{
"path": "src/memray/_memray/pthread.pxd",
"chars": 701,
"preview": "cdef extern from \"<pthread.h>\" nogil:\n ctypedef int pthread_t\n\n ctypedef struct pthread_attr_t:\n pass\n c"
},
{
"path": "src/memray/_memray/python_helpers.cpp",
"chars": 571,
"preview": "#include \"python_helpers.h\"\n\nnamespace memray::python_helpers {\nPyObject*\nPyUnicode_Cache::getUnicodeObject(const std::s"
},
{
"path": "src/memray/_memray/python_helpers.h",
"chars": 468,
"preview": "#pragma once\n\n#define PY_SSIZE_T_CLEAN\n#include <Python.h>\n\n#include <functional>\n#include <memory>\n#include <string>\n#i"
},
{
"path": "src/memray/_memray/record_reader.cpp",
"chars": 50727,
"preview": "#define __STDC_FORMAT_MACROS\n#define PY_SSIZE_T_CLEAN\n#include <Python.h>\n\n#include <algorithm>\n#include <array>\n#includ"
},
{
"path": "src/memray/_memray/record_reader.h",
"chars": 7975,
"preview": "#pragma once\n\n#define PY_SSIZE_T_CLEAN\n#include <Python.h>\n\n#include <assert.h>\n#include <limits>\n#include <memory>\n#inc"
},
{
"path": "src/memray/_memray/record_reader.pxd",
"chars": 2781,
"preview": "from _memray.records cimport AggregatedAllocation\nfrom _memray.records cimport Allocation\nfrom _memray.records cimport H"
},
{
"path": "src/memray/_memray/record_writer.cpp",
"chars": 27524,
"preview": "#include \"record_writer.h\"\n\n#include <algorithm>\n#include <array>\n#include <cerrno>\n#include <chrono>\n#include <cstring>"
},
{
"path": "src/memray/_memray/record_writer.h",
"chars": 3843,
"preview": "#pragma once\n\n#include <limits>\n#include <string>\n#include <type_traits>\n#include <unistd.h>\n\n#include \"sink.h\"\n\nnamespa"
},
{
"path": "src/memray/_memray/record_writer.pxd",
"chars": 2383,
"preview": "from _memray.records cimport AllocationRecord\nfrom _memray.records cimport CodeObjectInfo\nfrom _memray.records cimport F"
},
{
"path": "src/memray/_memray/records.cpp",
"chars": 5133,
"preview": "#define PY_SSIZE_T_CLEAN\n#include <Python.h>\n\n#include \"python_helpers.h\"\n#include \"records.h\"\n\nnamespace memray::tracki"
},
{
"path": "src/memray/_memray/records.h",
"chars": 8134,
"preview": "#pragma once\n\n#define PY_SSIZE_T_CLEAN\n#include <Python.h>\n\n#include <fstream>\n#include <mutex>\n#include <stddef.h>\n#inc"
},
{
"path": "src/memray/_memray/records.pxd",
"chars": 4069,
"preview": "from _memray.hooks cimport Allocator\nfrom libc.stdint cimport uint64_t\nfrom libc.stdint cimport uintptr_t\nfrom libcpp ci"
},
{
"path": "src/memray/_memray/sink.cpp",
"chars": 10139,
"preview": "#define PY_SSIZE_T_CLEAN\n#include <Python.h>\n\n#include <cerrno>\n#include <cstdio>\n\n#include <arpa/inet.h>\n#include <fcnt"
},
{
"path": "src/memray/_memray/sink.h",
"chars": 2456,
"preview": "#pragma once\n\n#include <cerrno>\n#include <memory>\n#include <string>\n#include <unistd.h>\n\n#include \"records.h\"\n\nnamespace"
}
]
// ... and 199 more files (download for full content)
About this extraction
This page contains the full source code of the bloomberg/memray GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 399 files (5.2 MB), approximately 1.4M tokens, and a symbol index with 2731 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.