[build-system] requires = ["setuptools>=77.0.1", "wheel", "Cython>=3.0.0"] build-backend = "setuptools.build_meta" [project] # Must match the PyPI Trusted Publisher registration exactly. name = "d810-cobra" version = "0.1.6" description = "CoBRA MBA-solver backend for d810 (mba-solve)" readme = "README.md" # Tracks d810's own floor. d810-ng 1.0.0b2 (cfg-recon-mainline) requires >=3.11, # and this package does nothing without the d810 that discovers it -- a 3.10 # wheel would install cleanly and then have no host able to load it. requires-python = ">= 3.11" license = "MIT" authors = [{ name = "w00tzenheimer" }] keywords = ["deobfuscation", "mba", "ida-pro", "hex-rays", "cobra"] classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Security", ] # d810 IS a hard dependency for activation and runtime use. The entry-point # target itself (`d810_cobra:MANIFEST`) is intentionally inert and can be read # without importing d810; activation resolves the plugin and then runtime code # imports d810.core.getLogger, d810.core.cache.CacheImpl, # d810.core.typing, and d810.hexrays.*. Only `expr` and `probe` are genuinely # standalone. # # Not circular: d810 never imports this package, it only discovers it through # the entry point. # # Caveat worth knowing: several of these are d810 INTERNALS rather than a # published API (d810.core.cache, d810.core.typing), so a d810 refactor can # break this package without a major version bump on either side. # # The floor is >=1.0.0b0, NOT >=0.6.6, and the difference is the whole point. # Being discovered at all requires d810.core.plugins (BackendRegistry and the # API-1 manifest/activation protocol) and d810.backends (the # `d810.backends` entry-point group and host-capability binding). d810-ng 0.6.6 # ships NEITHER -- # # >>> import d810.core.plugins # ImportError: cannot import name 'plugins' from 'd810.core' # # -- so against 0.6.6 this package installs, imports, builds its binding, and # is then never found: mba-solve is simply absent, indistinguishable from a # pass that ran and matched nothing. 0.1.0 shipped with >=0.6.6 and had exactly # that failure. # # v1.0.0 is d810-ng's cutover release -- the first to carry this seam -- # and betas carry it until then. The floor says 1.0.0b0, not 1.0.0, # because a pre-release sorts BEFORE its final (1.0.0b1 < 1.0.0) and pip # skips pre-releases unless a specifier opts in. >=1.0.0 would reject # every beta while reporting "no version satisfies the requirement" -- # reading as nothing-released rather than beta-excluded. >=1.0.0b0 # accepts 1.0.0b1, 1.0.0rc1 and 1.0.0 alike. # # A floor no released d810-ng satisfies yet is deliberate. pip refusing to # install with a version error naming the requirement is strictly better than # installing something inert, and it is the same principle the build applies: # fail loudly rather than yield a package that installs cleanly and simplifies # nothing. dependencies = ["d810-ng>=1.0.0b0"] [project.optional-dependencies] test = ["pytest>=8.0"] [project.urls] Homepage = "https://github.com/w00tzenheimer/d810-CoBRA" Issues = "https://github.com/w00tzenheimer/d810-CoBRA/issues" # This is the whole integration surface. d810's BackendRegistry scans this # group before its builtins, so an installed copy of this package supersedes # anything d810 ships under the same name. The group is deliberately # unversioned -- the compatibility contract lives in the manifest's # api_version, not in the entry-point name. [project.entry-points."d810.backends"] cobra = "d810_cobra:MANIFEST" [tool.setuptools] package-dir = { "" = "src" } [tool.setuptools.packages.find] where = ["src"] [tool.setuptools.package-data] # cobra_shim.h is no longer here: it moved to src/include, matching d810's own # layout. It reaches the sdist through MANIFEST.in instead -- package-data only # covers files inside an importable package, and a header is a build input, not # something a wheel consumer imports. d810_cobra = ["*.pyx", "*.pxd"] [tool.pytest.ini_options] testpaths = ["tests/unit"]