Description
pytest's "official" public API is exported by the pytest
package, and everything else is defined in the _pytest
package.
Currently, pytest
only contains APIs that users need to use directly: functions to be called, decorators, classes to be instantiated or subclasssed, globals. Other objects, which the user doesn't interact with directly, are not exported.
Typing extends the range of cases in which some object needs to be referred to by name. As long as the user can somehow reach an object, directly or indirectly, through some public API, they need to be able to refer to its type by name, due to type annotations.
To come up with a list of reachable but unexported types, I used the following categories:
-
Fixtures: built-in fixtures that are dependency-injected. To benefit from the types the user needs to type annotate them, for example:
def test_it(monkeypatch: MonkeyPatch) -> None: ...
-
Hooks: the user needs to be able to type annotate the arguments and return values of any hook.
-
Transitive: types that are referred to transitively by some other public API, e.g. return value of a function, method, context manager, public attribute etc.
See below for the list I came up with.
Questions for discussion:
-
Is this a problem we want to fix?
-
Most of these types are classes, that are not intended to be instantiated and/or subclassed by users, only internally.
2.1. Do we want to enforce this?
2.2. How do we enforce this? -
How do we want to officialy declare something as public API?
-
Which types from the list below are we actually ready to export?
-
Is there a category or specific types I missed?
I'll add my own thoughts on these questions in a separate reply.
Fixtures:
-
_pytest.fixtures.FixtureRequest
->pytest.FixtureRequest
-
_pytest.fixtures.SubRequest
-
_pytest.cacheprovider.Cache
->pytest.Cache
-
_pytest.capture.CaptureFixture
->pytest.CaptureFixture
-
_pytest.logging.LogCaptureFixture
->pytest.LogCaptureFixture
-
_pytest.pytester.Pytester
->pytest.Pytester
-
_pytest.pytester.Testdir
->pytest.Testdir
-
_pytest.tmpdir.TempdirFactory
->pytest.TempdirFactory
-
_pytest.tmpdir.TempPathFactory
->pytest.TempPathFactory
-
_pytest.monkeypatch.MonkeyPatch
->pytest.MonkeyPatch
-
_pytest.recwarn.WarningsRecorder
->pytest.WarningsRecorder
Hooks:
-
_pytest.config.Config
->pytest.Config
-
_pytest.config.PytestPluginManager
->pytest.PytestPluginManager
-
_pytest.config.argparsing.Parser
->pytest.Parser
-
_pytest.reports.CollectReport
->pytest.CollectReport
-
(Made private Make PyCollector an implementation detail - don't use in hook type annotation #9264)_pytest.python.PyCollector
-
_pytest.python.Metafunc
->pytest.Metafunc
-
_pytest.runner.CallInfo
->pytest.CallInfo
-
_pytest.reports.TestReport
->pytest.TestReport
-
_pytest.fixtures.SubRequest
-
_pytest.fixtures.FixtureDef
-
_pytest.terminal.TerminalReporter
-
_pytest._code.code.ExceptionRepr
-
_pytest.code.ExceptionInfo
->pytest.ExceptionInfo
API:
-
_pytest.mark.structures.ParameterSet
Transitive:
-
_pytest.fixtures.FuncFixtureInfo
(thruMetafunc
) -
_pytest.fixtures.FixtureFunctionMarker
-
_pytest.mark.structures.MarkGenerator
->pytest.MarkGenerator
-
_pytest.mark.structures.MarkDecorator
->pytest.MarkDecorator
-
_pytest.mark.structures.Mark
->pytest.Mark
-
- only exposed as a_pytest.mark.structures.NodeKeywords
(thruNode
)MutableMapping
instead. -
_pytest.code._code.TerminalRepr
-
_pytest.python.CallSpec2
-
_pytest.python_api.ApproxBase
-
- Not worth exposing, just a context manager._pytest.python_api.RaisesContext
-
_pytest.recwarn.WarningsRecorder
->pytest.WarningsRecorder
-
_pytest._io.TerminalWriter
-
_pytest.config.argparsing.OptionGroup
->pytest.OptionGroup
-
_pytest.pytester.ParsedCall
->pytest.RecordedHookCall
-
_pytest.pytester.HookRecorder
->pytest.HookRecorder
-
_pytest.pytester.RunResult
->pytest.RunResult
-
_pytest.pytester.LineMatcher
->pytest.LineMatcher