{"id":13538852,"url":"https://github.com/openstack/hacking","last_synced_at":"2025-05-16T02:07:16.819Z","repository":{"id":7677837,"uuid":"9040482","full_name":"openstack/hacking","owner":"openstack","description":"OpenStack Hacking Style Checks. Mirror of code maintained at opendev.org.","archived":false,"fork":false,"pushed_at":"2024-12-20T17:52:29.000Z","size":937,"stargazers_count":241,"open_issues_count":0,"forks_count":66,"subscribers_count":32,"default_branch":"master","last_synced_at":"2025-04-08T12:09:57.309Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://opendev.org/openstack/hacking","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openstack.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE","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-03-26T21:09:28.000Z","updated_at":"2025-02-03T11:38:30.000Z","dependencies_parsed_at":"2023-01-11T17:13:18.384Z","dependency_job_id":"80345247-a32f-41c9-a273-bd9b451554a4","html_url":"https://github.com/openstack/hacking","commit_stats":{"total_commits":738,"total_committers":189,"mean_commits":"3.9047619047619047","dds":0.8346883468834688,"last_synced_commit":"2931131b69af7f1e76d8ab506c250a94b330ffb9"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstack%2Fhacking","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstack%2Fhacking/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstack%2Fhacking/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openstack%2Fhacking/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openstack","download_url":"https://codeload.github.com/openstack/hacking/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254453651,"owners_count":22073617,"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":[],"created_at":"2024-08-01T09:01:16.956Z","updated_at":"2025-05-16T02:07:16.800Z","avatar_url":"https://github.com/openstack.png","language":"Python","readme":"Introduction\n============\n\nhacking is a set of flake8 plugins that test and enforce the\n`OpenStack StyleGuide \u003chttps://docs.openstack.org/hacking/latest/user/hacking.html#styleguide\u003e`_\n\nHacking pins its dependencies, as a new release of some dependency can break\nhacking based gating jobs. This is because new versions of dependencies can\nintroduce new rules, or make existing rules stricter.\n\nInstallation\n============\n\nhacking is available from pypi, so just run::\n\n  pip install hacking\n\nThis will install specific versions of ``flake8`` with the ``hacking``,\n``pep8``, ``mccabe`` and ``pyflakes`` plugins.\n\nOrigin\n======\n\nHacking started its life out as a text file in Nova's first commit. It was\ninitially based on the `Google Python Style Guide`_, and over time more\nOpenStack specific rules were added. Hacking serves several purposes:\n\n1. Agree on a common style guide so reviews don't get bogged down on style\n   nit picks. (example: docstring guidelines)\n2. Make code written by many different authors easier to read by making the\n   style more uniform. (example: unix vs windows newlines)\n3. Call out dangerous patterns and avoid them. (example: shadowing built-in\n   or reserved words)\n\nInitially the hacking style guide was enforced manually by reviewers, but this\nwas a big waste of time so hacking, the tool, was born to automate\nthe process and remove the extra burden from human reviewers.\n\n.. _`Google Python Style Guide`: https://google.github.io/styleguide/pyguide.html\n\nVersioning\n==========\n\nhacking uses the ``major.minor.maintenance`` release notation, where maintenance\nreleases cannot contain new checks.  This way projects can gate on hacking\nby pinning on the ``major.minor`` number while accepting maintenance updates\nwithout being concerned that a new version will break the gate with a new\ncheck.\n\nFor example a project can depend on ``hacking\u003e=0.10.0,\u003c0.11.0``, and can know\nthat ``0.10.1`` will not fail in places where ``0.10.0`` passed.\n\n\nAdding additional checks\n========================\n\nEach check is a pep8 plugin so read\n\n- https://github.com/jcrocholl/pep8/blob/master/docs/developer.rst#contribute\n\nThe focus of new or changed rules should be to do one of the following\n\n- Substantially increase the reviewability of the code (eg: H301, H303)\n  as they make it easy to understand where symbols come from)\n- Catch a common programming error that may arise in the future (H201)\n- Prevent a situation that would 100% of the time be -1ed by\n  developers (H903)\n\nBut, as always, remember that these are Guidelines. Treat them as\nsuch. There are always times for exceptions. All new rules should\nsupport noqa.\n\nIf a check needs to be staged in, or it does not apply to every project or its\nbranch, it can be added as off by default.\n\nRequirements\n------------\n- The check must already have community support. We do not want to dictate\n  style, only enforce it.\n- The canonical source of the OpenStack Style Guidelines is\n  `StyleGuide \u003chttps://docs.openstack.org/hacking/latest/user/hacking.html#styleguide\u003e`_,\n  and hacking just enforces\n  them; so when adding a new check, it must be in ``HACKING.rst``\n- False negatives are ok, but false positives are not\n- Cannot be project specific, project specific checks should be `Local Checks`_\n- Include extensive tests\n- Registered as entry_points in ``setup.cfg``\n- Error code must be in the relevant ``Hxxx`` group\n- The check should not attempt to import modules from the code being checked.\n  Importing random modules, has caused all kinds of trouble for us in the past.\n\n\nEnabling off-by-default checks\n==============================\n\nSome of the available checks are disabled by default. These checks are:\n\n- [H106] Don't put vim configuration in source files.\n- [H203] Use assertIs(Not)None to check for None.\n- [H204] Use assert(Not)Equal to check for equality.\n- [H205] Use assert(Greater|Less)(Equal) for comparison.\n- [H210] Require 'autospec', 'spec', or 'spec_set' in\n  mock.patch/mock.patch.object calls\n- [H904] Delay string interpolations at logging calls.\n\nTo enable these checks, edit the ``flake8`` section of the ``tox.ini`` file.\nFor example to enable H106 and H203:\n\n.. code-block:: ini\n\n  [flake8]\n  enable-extensions = H106,H203\n\nLocal Checks\n============\n\nhacking supports having local changes in a source tree. They need to\nbe registered individually in tox.ini:\n\nAdd to tox.ini a new section ``flake8:local-plugins`` and list each plugin with\nits entry-point. Additionally, you can add the path to the files\ncontaining the plugins so that the repository does not need to be\ninstalled with the ``paths`` directive.\n\n.. code-block:: ini\n\n   [flake8:local-plugins]\n   extension =\n     N307 = checks:import_no_db_in_virt\n     N325 = checks:CheckForStrUnicodeExc\n   paths =\n     ./nova/hacking\n\nThe plugins, in the example above they live in\n``nova/hacking/checks.py``, need to annotate all functions with ``@core.flake8ext``\n\n.. code-block:: python\n\n   from hacking import core\n   ...\n   @core.flake8ext\n   def import_no_db_in_virt(logical_line, filename):\n       ...\n\n   class CheckForStrUnicodeExc(BaseASTChecker):\n      name = \"check_for_str_unicode_exc\"\n      version = \"1.0\"\n      ...\n\nFurther details are part of the `flake8 documentation\n\u003chttps://flake8.pycqa.org/en/latest/plugin-development/index.html\u003e`_.\n","funding_links":[],"categories":["Python (1887)","Python","\u003ca id=\"9eee96404f868f372a6cbc6769ccb7f8\"\u003e\u003c/a\u003e工具","Linters \u0026 Style Checkers","All-in-one"],"sub_categories":["\u003ca id=\"31185b925d5152c7469b963809ceb22d\"\u003e\u003c/a\u003e新添加的"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenstack%2Fhacking","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenstack%2Fhacking","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenstack%2Fhacking/lists"}