{"id":15032425,"url":"https://github.com/cool-rr/pysnooper","last_synced_at":"2026-10-18T22:02:32.857Z","repository":{"id":37251511,"uuid":"182097305","full_name":"cool-RR/PySnooper","owner":"cool-RR","description":"Never use print for debugging again","archived":false,"fork":false,"pushed_at":"2026-06-08T19:45:15.000Z","size":447,"stargazers_count":16577,"open_issues_count":34,"forks_count":967,"subscribers_count":232,"default_branch":"master","last_synced_at":"2026-10-09T20:28:12.323Z","etag":null,"topics":["debug","debugger","introspection","logging","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cool-RR.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"claude":null,"gemini":null,"cursor":null,"copilot":null,"dco":null,"cla":null,"disclosure":null}},"created_at":"2019-04-18T13:55:43.000Z","updated_at":"2026-10-06T08:55:30.000Z","dependencies_parsed_at":"2023-02-01T06:10:12.444Z","dependency_job_id":"8fd431d2-02db-4c9c-9971-133bda0fb103","html_url":"https://github.com/cool-RR/PySnooper","commit_stats":{"total_commits":307,"total_committers":29,"mean_commits":"10.586206896551724","dds":"0.46579804560260585","last_synced_commit":"caf4ec584a87e4bfa699781191ef1c7580981705"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/cool-RR/PySnooper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cool-RR%2FPySnooper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cool-RR%2FPySnooper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cool-RR%2FPySnooper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cool-RR%2FPySnooper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cool-RR","download_url":"https://codeload.github.com/cool-RR/PySnooper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cool-RR%2FPySnooper/sbom","scorecard":{"id":304001,"data":{"date":"2025-08-11","repo":{"name":"github.com/cool-RR/PySnooper","commit":"0561a89c0ec88d11f38c6ef815d12c0423300fe1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":1,"reason":"Found 4/30 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":2,"reason":"2 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 8 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T21:31:47.672Z","repository_id":37251511,"created_at":"2025-08-17T21:31:47.672Z","updated_at":"2025-08-17T21:31:47.672Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":344872684,"owners_count":38342694,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-10-03T21:59:58.778Z","status":"online","status_checked_at":"2026-10-18T02:00:06.448Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["debug","debugger","introspection","logging","python"],"created_at":"2024-09-24T20:18:22.180Z","updated_at":"2026-10-18T22:02:32.563Z","avatar_url":"https://github.com/cool-RR.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PySnooper - Never use print for debugging again\n\n**PySnooper** is a poor man's debugger. If you've used Bash, it's like `set -x` for Python, except it's fancier.\n\nYour story: You're trying to figure out why your Python code isn't doing what you think it should be doing. You'd love to use a full-fledged debugger with breakpoints and watches, but you can't be bothered to set one up right now.\n\nYou want to know which lines are running and which aren't, and what the values of the local variables are.\n\nMost people would use `print` lines, in strategic locations, some of them showing the values of variables.\n\n**PySnooper** lets you do the same, except instead of carefully crafting the right `print` lines, you just add one decorator line to the function you're interested in. You'll get a play-by-play log of your function, including which lines ran and   when, and exactly when local variables were changed.\n\nWhat makes **PySnooper** stand out from all other code intelligence tools? You can use it in your shitty, sprawling enterprise codebase without having to do any setup. Just slap the decorator on, as shown below, and redirect the output to a dedicated log file by specifying its path as the first argument.\n\n## Example\n\nWe're writing a function that converts a number to binary, by returning a list of bits. Let's snoop on it by adding the `@pysnooper.snoop()` decorator:\n\n```python\nimport pysnooper\n\n@pysnooper.snoop()\ndef number_to_bits(number):\n    if number:\n        bits = []\n        while number:\n            number, remainder = divmod(number, 2)\n            bits.insert(0, remainder)\n        return bits\n    else:\n        return [0]\n\nnumber_to_bits(6)\n```\nThe output to stderr is:\n\n![](https://i.imgur.com/TrF3VVj.jpg)\n\nOr if you don't want to trace an entire function, you can wrap the relevant part in a `with` block:\n\n```python\nimport pysnooper\nimport random\n\ndef foo():\n    lst = []\n    for i in range(10):\n        lst.append(random.randrange(1, 1000))\n\n    with pysnooper.snoop():\n        lower = min(lst)\n        upper = max(lst)\n        mid = (lower + upper) / 2\n        print(lower, mid, upper)\n\nfoo()\n```\n\nwhich outputs something like:\n\n```\nNew var:....... i = 9\nNew var:....... lst = [681, 267, 74, 832, 284, 678, ...]\n09:37:35.881721 line        10         lower = min(lst)\nNew var:....... lower = 74\n09:37:35.882137 line        11         upper = max(lst)\nNew var:....... upper = 832\n09:37:35.882304 line        12         mid = (lower + upper) / 2\n74 453.0 832\nNew var:....... mid = 453.0\n09:37:35.882486 line        13         print(lower, mid, upper)\nElapsed time: 00:00:00.000344\n```\n\n## Features\n\nIf stderr is not easily accessible for you, you can redirect the output to a file:\n\n```python\n@pysnooper.snoop('/my/log/file.log')\n```\n\nYou can also pass a stream or a callable instead, and they'll be used.\n\nSee values of some expressions that aren't local variables:\n\n```python\n@pysnooper.snoop(watch=('foo.bar', 'self.x[\"whatever\"]'))\n```\n\nShow snoop lines for functions that your function calls:\n\n```python\n@pysnooper.snoop(depth=2)\n```\n\n**See [Advanced Usage](https://github.com/cool-RR/PySnooper/blob/master/ADVANCED_USAGE.md) for more options.** \u003c------\n\n\n## Installation with Pip\n\nThe best way to install **PySnooper** is with Pip:\n\n```console\n$ pip install pysnooper\n```\n\n## Other installation options\n\nConda with conda-forge channel:\n\n```console\n$ conda install -c conda-forge pysnooper\n```\n\nArch Linux:\n\n```console\n$ yay -S python-pysnooper\n```\n\nFedora Linux:\n\n```console\n$ dnf install python3-pysnooper\n```\n\n\n## Citing PySnooper\n\nIf you use PySnooper in academic work, please use this citation format:\n\n```bibtex\n@software{rachum2019pysnooper,\n    title={PySnooper: Never use print for debugging again},\n    author={Rachum, Ram and Hall, Alex and Yanokura, Iori and others},\n    year={2019},\n    month={jun},\n    publisher={PyCon Israel},\n    doi={10.5281/zenodo.10462459},\n    url={https://github.com/cool-RR/PySnooper}\n}\n```\n\n\n## License\n\nCopyright (c) 2019 Ram Rachum and collaborators, released under the MIT license.\n\n\n## Media Coverage\n\n[Hacker News thread](https://news.ycombinator.com/item?id=19717786)\nand [/r/Python Reddit thread](https://www.reddit.com/r/Python/comments/bg0ida/pysnooper_never_use_print_for_debugging_again/) (22 April 2019)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcool-rr%2Fpysnooper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcool-rr%2Fpysnooper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcool-rr%2Fpysnooper/lists"}