{"id":17720354,"url":"https://github.com/sdiehl/subpy","last_synced_at":"2025-07-11T03:30:59.556Z","repository":{"id":137839185,"uuid":"11137185","full_name":"sdiehl/subpy","owner":"sdiehl","description":"Python subsets","archived":false,"fork":false,"pushed_at":"2017-02-11T13:44:03.000Z","size":38,"stargazers_count":41,"open_issues_count":0,"forks_count":7,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-03-11T04:30:04.502Z","etag":null,"topics":["ast","python","static-analysis"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sdiehl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-07-02T22:57:50.000Z","updated_at":"2021-08-28T18:11:00.000Z","dependencies_parsed_at":null,"dependency_job_id":"f8796e98-13f9-4c7e-870a-c99cd92fe69d","html_url":"https://github.com/sdiehl/subpy","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/sdiehl/subpy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdiehl%2Fsubpy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdiehl%2Fsubpy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdiehl%2Fsubpy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdiehl%2Fsubpy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sdiehl","download_url":"https://codeload.github.com/sdiehl/subpy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sdiehl%2Fsubpy/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264721295,"owners_count":23653915,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["ast","python","static-analysis"],"created_at":"2024-10-25T15:26:43.086Z","updated_at":"2025-07-11T03:30:59.267Z","avatar_url":"https://github.com/sdiehl.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"\u003cp align=\"center\" style=\"padding: 20px\"\u003e\n\u003cimg src=\"https://raw.github.com/sdiehl/subpy/master/logo_sml.png\"\u003e\n\u003c/p\u003e\n\nSubpy\n=====\n\nSubpy is a library for defining subsets of the Python language\nand querying ASTs for language-level properties that are\nspecified as sets of features.\n\nMany projects aim to work with specific subsets of Python that\nare amenable to *static analysis* and *type inference*, subpy is\nsimply a static analysis  library for checking for subsets with\nthe intention of providing more informative error reporting for\nend-users.\n\nUsage\n-----\n\nThe input to the ``checker`` can be either a Module, Function or\nsource code as string. It returns a dictionary of lists keyed by\nthe ``feature`` enumeration code and the values with the line\nnumbers where the feature is detected. \n\n```python\n\u003e\u003e\u003e from subpy import checker\n\u003e\u003e\u003e import io\n\n\u003e\u003e\u003e print checker(io)\n\n{3: [98],\n 5: [78, 81, 84, 87],\n 9: [78, 81, 84, 87],\n 10: [81, 84, 87],\n 32: [92, 96],\n 34: [79]}\n```\n\nMatching the feature codes with the keys in the dictionary we see\nthe information this is telling us that in the ``io`` module in\nthe standard library:\n\n* A *delete* is used on line 98.\n* A *class* is used on line 78, 81, 84, and 87.\n* *Inheritance* is used on line 78, 81, 84, and 87.\n* *Multiple inheritance* is used on line 81, 84, and 87.\n* A *custom iterator* is used on line 92 and 96.\n* A *metaclass* is used on line 79.\n\nA example using the function level checker:\n\n```python\nfrom subpy import checker\nfrom subpy.features import ListComp\n\ndef example1():\n    return [x**2 for x in range(25)]\n\ndef example2():\n    return 'hello'\n\nfeatures = checker(example1)\n\nif ListComp in features:\n    print 'You used a list comprehension on lines %r' % (features[ListComp])\n\nfeatures = checker(example2)\n\nif ListComp not in features:\n    print 'You did not use any list comprehensions!'\n\n```\n\nDefining Subsets\n----------------\n\nFor example if we want to exclude the use of *List Comprehensions*\nand *Set Comprehensions* we could define a subset of Python that\nexcludes these features.\n\n```python\nMyPythonSubset = FullPython - { ListComp, SetComp }\n```\n\nThe ``validator`` command can be used to raise when unsupported\nfeatures are detected in the given source. For example, we'll\nsupport the python feature set excluding list comprehensions and\nset comprehensions.\n\n```python\nfrom subpy import validator, FullPython, FeatureNotSupported\nfrom subpy.features import ListComp, SetComp\n\ndef example():\n    return [x**2 for x in range(25)]\n\nmy_features = FullPython - { ListComp, SetComp }\n\nvalidator(example, features=my_features)\n```\n\n```python\n  File \"\u003cstdin\u003e\", line 2\n    return [x**2 for x in range(25)]\n            ^\nsubpy.validate.FeatureNotSupported: ListComp\n```\n\nSubpy is currently able to parse the entire standard library and\ncan be used to query some interesting trivia facts.\n\n```python\nfrom subpy import detect\nfrom subpy.stdlib import libraries\nfrom subpy.features import Metaclasses, MInheritance, Exec\n\nimport importlib\n\nprint('Libraries with Multiple Inheritance and Metaclasses:')\nfor lib in libraries:\n    mod = importlib.import_module(lib)\n    features = detect(mod)\n\n    if Metaclasses in features and MInheritance in features:\n        print(lib)\n\n```\n\n```\nLibraries with Multiple Inheritance and Metaclasses:\nio\n```\n\nOr to query for potentially unsafe code execution:\n\n```python\nprint('Libraries with Exec')\nfor lib in libraries:\n    mod = importlib.import_module(lib)\n    features = detect(mod)\n\n    if Exec in features:\n        print(lib)\n```\n\n```\nLibraries with Exec\nihooks\nsite\ncgi\nrexec\nBastion\nimputil\ntrace\ntimeit\ncProfile\ndoctest\ncode\nbdb\nrunpy\nprofile\ncollections\n```\n\nFeature Codes\n-------------\n\nCurrently supported features are an enumeration with values given\nbelow:\n\n1. ImplicitCasts\n1. Generators\n1. DelVar\n1. Closures\n1. Classes\n1. Decorators\n1. VarArgs\n1. KeywordArgs\n1. Inheritance\n1. MInheritance\n1. ClassDecorators\n1. Assertions\n1. ChainComparison\n1. Exceptions\n1. Lambda\n1. RelativeImports\n1. ImportStar\n1. HeteroList\n1. Continue\n1. MultipleReturn\n1. DictComp\n1. Ellipsi\n1. TupleUnpacking\n1. Exec\n1. FancyIndexing\n1. Globals\n1. ContextManagers\n1. GeneratorExp\n1. Ternary\n1. ListComp\n1. SetComp\n1. CustomIterators\n1. Printing\n1. Metaclasses\n\nTesting\n-------\n\nTo test run:\n\n```bash\n$ python -m unittest discover subpy/tests\n```\n\nCopying\n-------\n\nThe core logic is self-contained in ``features.py`` and\n``validate.py`` which will function as standalone modules without\nsubpy package, which includes the test suite. There are no\ndependencies other than the standard library.\n\nLicense\n-------\n\nCopyright (c) 2013, Continuum Analytics, Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\nRedistributions of source code must retain the above copyright notice,\nthis list of conditions and the following disclaimer.\n\nRedistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsdiehl%2Fsubpy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsdiehl%2Fsubpy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsdiehl%2Fsubpy/lists"}