diff --git a/poetry.lock b/poetry.lock index bbf88e6..e056b6e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,16 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.0 and should not be changed by hand. + +[[package]] +name = "annotated-types" +version = "0.6.0" +description = "Reusable constraint types to use with typing.Annotated" +category = "main" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, + {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, +] [[package]] name = "annotated-types" @@ -15,6 +27,7 @@ files = [ name = "asttokens" version = "2.4.1" description = "Annotate AST trees with source code positions" +category = "dev" optional = false python-versions = "*" files = [ @@ -33,6 +46,7 @@ test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] name = "certifi" version = "2023.11.17" description = "Python package for providing Mozilla's CA Bundle." +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -44,6 +58,7 @@ files = [ name = "cffi" version = "1.16.0" description = "Foreign Function Interface for Python calling C code." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -108,6 +123,7 @@ pycparser = "*" name = "charset-normalizer" version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -207,6 +223,7 @@ files = [ name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -285,6 +302,7 @@ toml = ["tomli"] name = "cryptography" version = "41.0.7" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -330,6 +348,7 @@ test-randomorder = ["pytest-randomly"] name = "decorator" version = "5.1.1" description = "Decorators for Humans" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -341,6 +360,7 @@ files = [ name = "docstring-to-markdown" version = "0.13" description = "On the fly conversion of Python docstrings to markdown" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -352,6 +372,7 @@ files = [ name = "docutils" version = "0.20.1" description = "Docutils -- Python Documentation Utilities" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -363,6 +384,7 @@ files = [ name = "exceptiongroup" version = "1.2.0" description = "Backport of PEP 654 (exception groups)" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -377,6 +399,7 @@ test = ["pytest (>=6)"] name = "executing" version = "2.0.1" description = "Get the currently executing AST node of a frame, and other information" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -391,6 +414,7 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth name = "idna" version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -402,6 +426,7 @@ files = [ name = "importlib-metadata" version = "7.0.0" description = "Read metadata from Python packages" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -421,6 +446,7 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -432,6 +458,7 @@ files = [ name = "ipdb" version = "0.13.13" description = "IPython-enabled pdb" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -448,6 +475,7 @@ tomli = {version = "*", markers = "python_version > \"3.6\" and python_version < name = "ipython" version = "8.18.1" description = "IPython: Productive Interactive Computing" +category = "dev" optional = false python-versions = ">=3.9" files = [ @@ -484,6 +512,7 @@ test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.22)", "pa name = "jaraco-classes" version = "3.3.0" description = "Utility functions for Python class constructs" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -502,6 +531,7 @@ testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", name = "jedi" version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -521,6 +551,7 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] name = "jeepney" version = "0.8.0" description = "Low-level, pure Python DBus protocol wrapper." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -536,6 +567,7 @@ trio = ["async_generator", "trio"] name = "keyring" version = "24.3.0" description = "Store and access your passwords safely." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -559,6 +591,7 @@ testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", name = "markdown-it-py" version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -583,6 +616,7 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -597,6 +631,7 @@ traitlets = "*" name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -608,6 +643,7 @@ files = [ name = "more-itertools" version = "10.1.0" description = "More routines for operating on iterables, beyond itertools" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -644,6 +680,7 @@ files = [ name = "packaging" version = "23.2" description = "Core utilities for Python packages" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -655,6 +692,7 @@ files = [ name = "parso" version = "0.8.3" description = "A Python Parser" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -670,6 +708,7 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "pexpect" version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." +category = "dev" optional = false python-versions = "*" files = [ @@ -684,6 +723,7 @@ ptyprocess = ">=0.5" name = "pkginfo" version = "1.9.6" description = "Query metadata from sdists / bdists / installed packages." +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -698,6 +738,7 @@ testing = ["pytest", "pytest-cov"] name = "pluggy" version = "1.3.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -713,6 +754,7 @@ testing = ["pytest", "pytest-benchmark"] name = "prompt-toolkit" version = "3.0.43" description = "Library for building powerful interactive command lines in Python" +category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -727,6 +769,7 @@ wcwidth = "*" name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" +category = "dev" optional = false python-versions = "*" files = [ @@ -738,6 +781,7 @@ files = [ name = "pure-eval" version = "0.2.2" description = "Safely evaluate AST nodes without side effects" +category = "dev" optional = false python-versions = "*" files = [ @@ -752,6 +796,7 @@ tests = ["pytest"] name = "pycparser" version = "2.21" description = "C parser in Python" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -899,6 +944,7 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" name = "pygments" version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -914,6 +960,7 @@ windows-terminal = ["colorama (>=0.4.6)"] name = "pytest" version = "7.4.3" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -954,6 +1001,7 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "python-lsp-jsonrpc" version = "1.1.2" description = "JSON RPC 2.0 server library" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -971,6 +1019,7 @@ test = ["coverage", "pycodestyle", "pyflakes", "pylint", "pytest", "pytest-cov"] name = "python-lsp-server" version = "1.9.0" description = "Python Language Server for the Language Server Protocol" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1003,6 +1052,7 @@ yapf = ["whatthepatch (>=1.0.2,<2.0.0)", "yapf (>=0.33.0)"] name = "pywin32-ctypes" version = "0.2.2" description = "A (partial) reimplementation of pywin32 using ctypes/cffi" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1014,6 +1064,7 @@ files = [ name = "readme-renderer" version = "42.0" description = "readme_renderer is a library for rendering readme descriptions for Warehouse" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1033,6 +1084,7 @@ md = ["cmarkgfm (>=0.8.0)"] name = "requests" version = "2.31.0" description = "Python HTTP for Humans." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1054,6 +1106,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-toolbelt" version = "1.0.0" description = "A utility belt for advanced users of python-requests" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1068,6 +1121,7 @@ requests = ">=2.0.1,<3.0.0" name = "rfc3986" version = "2.0.0" description = "Validating URI References per RFC 3986" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1082,6 +1136,7 @@ idna2008 = ["idna"] name = "rich" version = "13.7.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +category = "dev" optional = false python-versions = ">=3.7.0" files = [ @@ -1100,6 +1155,7 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] name = "ruff" version = "0.1.8" description = "An extremely fast Python linter and code formatter, written in Rust." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1126,6 +1182,7 @@ files = [ name = "secretstorage" version = "3.3.3" description = "Python bindings to FreeDesktop.org Secret Service API" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1141,6 +1198,7 @@ jeepney = ">=0.6" name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1152,6 +1210,7 @@ files = [ name = "stack-data" version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" +category = "dev" optional = false python-versions = "*" files = [ @@ -1171,6 +1230,7 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1182,6 +1242,7 @@ files = [ name = "traitlets" version = "5.14.0" description = "Traitlets Python configuration system" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1197,6 +1258,7 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, name = "twine" version = "4.0.2" description = "Collection of utilities for publishing packages on PyPI" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1230,6 +1292,7 @@ files = [ name = "ujson" version = "5.9.0" description = "Ultra fast JSON encoder and decoder for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1304,6 +1367,7 @@ files = [ name = "urllib3" version = "2.1.0" description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1320,6 +1384,7 @@ zstd = ["zstandard (>=0.18.0)"] name = "wcwidth" version = "0.2.12" description = "Measures the displayed width of unicode strings in a terminal" +category = "dev" optional = false python-versions = "*" files = [ @@ -1331,6 +1396,7 @@ files = [ name = "zipp" version = "3.17.0" description = "Backport of pathlib-compatible object wrapper for zip files" +category = "dev" optional = false python-versions = ">=3.8" files = [ diff --git a/pylspclient/lsp_structs.py b/pylspclient/lsp_structs.py index d6dbdd2..2c9de0e 100644 --- a/pylspclient/lsp_structs.py +++ b/pylspclient/lsp_structs.py @@ -1,5 +1,6 @@ import enum - +from pydantic import BaseModel, ConfigDict +from typing import Optional, Any, List def to_type(o, new_type): ''' @@ -14,358 +15,287 @@ def to_type(o, new_type): return new_type(**o) -class Position(object): - def __init__(self, line, character): - """ - Constructs a new Position instance. +class Position(BaseModel): + """ + Constructs a new Position instance. - :param int line: Line position in a document (zero-based). - :param int character: Character offset on a line in a document (zero-based). - """ - self.line = line - self.character = character + :param int line: Line position in a document (zero-based). + :param int character: Character offset on a line in a document (zero-based). + """ + line: int + character: int -class Range(object): - def __init__(self, start, end): - """ - Constructs a new Range instance. +class Range(BaseModel): + """ + Constructs a new Range instance. - :param Position start: The range's start position. - :param Position end: The range's end position. - """ - self.start = to_type(start, Position) - self.end = to_type(end, Position) + :param Position start: The range's start position. + :param Position end: The range's end position. + """ + start: Position + end: Position -class Location(object): +class Location(BaseModel): """ Represents a location inside a resource, such as a line inside a text file. """ - def __init__(self, uri, range): - """ - Constructs a new Location instance. - - :param str uri: Resource file. - :param Range range: The range inside the file - """ - self.uri = uri - self.range = to_type(range, Range) + uri: str + range: Range -class LocationLink(object): +class LocationLink(BaseModel): """ Represents a link between a source and a target location. + Constructs a new LocationLink instance. + + :param Range originSelectionRange: Span of the origin of this link. + Used as the underlined span for mouse interaction. Defaults to the word range at the mouse position. + :param str targetUri: The target resource identifier of this link. + :param Range targetRange: The full target range of this link. If the target for example is a symbol then target + range is the range enclosing this symbol not including leading/trailing whitespace but everything else + like comments. This information is typically used to highlight the range in the editor. + :param Range targetSelectionRange: The range that should be selected and revealed when this link is being followed, + e.g the name of a function. Must be contained by the the `targetRange`. See also `DocumentSymbol#range` """ - def __init__(self, originSelectionRange, targetUri, targetRange, targetSelectionRange): - """ - Constructs a new LocationLink instance. - - :param Range originSelectionRange: Span of the origin of this link. - Used as the underlined span for mouse interaction. Defaults to the word range at the mouse position. - :param str targetUri: The target resource identifier of this link. - :param Range targetRange: The full target range of this link. If the target for example is a symbol then target - range is the range enclosing this symbol not including leading/trailing whitespace but everything else - like comments. This information is typically used to highlight the range in the editor. - :param Range targetSelectionRange: The range that should be selected and revealed when this link is being followed, - e.g the name of a function. Must be contained by the the `targetRange`. See also `DocumentSymbol#range` - """ - self.originSelectionRange = to_type(originSelectionRange, Range) - self.targetUri = targetUri - self.targetRange = to_type(targetRange, Range) - self.targetSelectionRange = to_type(targetSelectionRange, Range) - - -class Diagnostic(object): - def __init__(self, range, severity, code, source, message, relatedInformation): - """ - Constructs a new Diagnostic instance. - :param Range range: The range at which the message applies.Resource file. - :param int severity: The diagnostic's severity. Can be omitted. If omitted it is up to the - client to interpret diagnostics as error, warning, info or hint. - :param str code: The diagnostic's code, which might appear in the user interface. - :param str source: A human-readable string describing the source of this - diagnostic, e.g. 'typescript' or 'super lint'. - :param str message: The diagnostic's message. - :param list relatedInformation: An array of related diagnostic information, e.g. when symbol-names within - a scope collide all definitions can be marked via this property. - """ - self.range = range - self.severity = severity - self.code = code - self.source = source - self.message = message - self.relatedInformation = relatedInformation + originSelectionRange: Range + targetUri: str + targetRange: Range + targetSelectionRange: Range -class DiagnosticSeverity(object): - Error = 1 - Warning = 2 # TODO: warning is known in python - Information = 3 - Hint = 4 - - -class DiagnosticRelatedInformation(object): - def __init__(self, location, message): - """ - Constructs a new Diagnostic instance. - :param Location location: The location of this related diagnostic information. - :param str message: The message of this related diagnostic information. - """ - self.location = location - self.message = message +class Diagnostic(BaseModel): + """ + Constructs a new Diagnostic instance. + :param Range range: The range at which the message applies.Resource file. + :param int severity: The diagnostic's severity. Can be omitted. If omitted it is up to the + client to interpret diagnostics as error, warning, info or hint. + :param str code: The diagnostic's code, which might appear in the user interface. + :param str source: A human-readable string describing the source of this + diagnostic, e.g. 'typescript' or 'super lint'. + :param str message: The diagnostic's message. + :param list relatedInformation: An array of related diagnostic information, e.g. when symbol-names within + a scope collide all definitions can be marked via this property. + """ + range: Range + severity: int + code: str + source: str + message: str + relatedInformation: list + - -class Command(object): - def __init__(self, title, command, arguments): - """ - Constructs a new Diagnostic instance. - :param str title: Title of the command, like `save`. - :param str command: The identifier of the actual command handler. - :param list argusments: Arguments that the command handler should be invoked with. - """ - self.title = title - self.command = command - self.arguments = arguments +class DiagnosticSeverity(object): + Error: int = 1 + Warning: int = 2 # TODO: warning is known in python + Information: int = 3 + Hint: int = 4 -class TextDocumentItem(object): +class DiagnosticRelatedInformation(BaseModel): """ - An item to transfer a text document from the client to the server. + Constructs a new Diagnostic instance. + :param Location location: The location of this related diagnostic information. + :param str message: The message of this related diagnostic information. """ - def __init__(self, uri, languageId, version, text): - """ - Constructs a new Diagnostic instance. - - :param DocumentUri uri: Title of the command, like `save`. - :param str languageId: The identifier of the actual command handler. - :param int version: Arguments that the command handler should be invoked with. - :param str text: Arguments that the command handler should be invoked with. - """ - self.uri = uri - self.languageId = languageId - self.version = version - self.text = text + location: Location + message: str -class TextDocumentIdentifier(object): +class Command(BaseModel): """ - Text documents are identified using a URI. On the protocol level, URIs are passed as strings. + Constructs a new Diagnostic instance. + :param str title: Title of the command, like `save`. + :param str command: The identifier of the actual command handler. + :param list arguments: Arguments that the command handler should be invoked with. """ - def __init__(self, uri): - """ - Constructs a new TextDocumentIdentifier instance. + title: str + command: str + arguments: list - :param DocumentUri uri: The text document's URI. - """ - self.uri = uri - -class VersionedTextDocumentIdentifier(TextDocumentIdentifier): +class TextDocumentItem(BaseModel): """ - An identifier to denote a specific version of a text document. + An item to transfer a text document from the client to the server. + Constructs a new Diagnostic instance. + + :param DocumentUri uri: Title of the command, like `save`. + :param str languageId: The identifier of the actual command handler. + :param int version: Arguments that the command handler should be invoked with. + :param str text: Arguments that the command handler should be invoked with. """ - def __init__(self, uri, version): - """ - Constructs a new TextDocumentIdentifier instance. - - :param DocumentUri uri: The text document's URI. - :param int version: The version number of this document. If a versioned - text document identifier is sent from the server to the client and - the file is not open in the editor (the server has not received an - open notification before) the server can send `null` to indicate - that the version is known and the content on disk is the truth (as - speced with document content ownership). - The version number of a document will increase after each change, including - undo/redo. The number doesn't need to be consecutive. - """ - super(VersionedTextDocumentIdentifier, self).__init__(uri) - self.version = version + uri: str + languageId: str + version: int + text: str -class TextDocumentContentChangeEvent(object): +class TextDocumentIdentifier(BaseModel): + """ + Text documents are identified using a URI. On the protocol level, URIs are passed as strings. + Constructs a new TextDocumentIdentifier instance. + + :param DocumentUri uri: The text document's URI. + """ + uri: str + +class VersionedTextDocumentIdentifier(TextDocumentIdentifier): + version: int +# class VersionedTextDocumentIdentifier(TextDocumentIdentifier): +# """ +# An identifier to denote a specific version of a text document. +# """ +# def __init__(self, version, uri): +# """ +# Constructs a new TextDocumentIdentifier instance. + +# :param DocumentUri uri: The text document's URI. +# :param int version: The version number of this document. If a versioned +# text document identifier is sent from the server to the client and +# the file is not open in the editor (the server has not received an +# open notification before) the server can send `null` to indicate +# that the version is known and the content on disk is the truth (as +# speced with document content ownership). +# The version number of a document will increase after each change, including +# undo/redo. The number doesn't need to be consecutive. +# """ +# self.version = version +# super(VersionedTextDocumentIdentifier, self).__init__(uri=uri) + + +class TextDocumentContentChangeEvent(BaseModel): """ An event describing a change to a text document. If range and rangeLength are omitted the new text is considered to be the full content of the document. - """ - def __init__(self, range, rangeLength, text): - """ - Constructs a new TextDocumentContentChangeEvent instance. + Constructs a new TextDocumentContentChangeEvent instance. - :param Range range: The range of the document that changed. - :param int rangeLength: The length of the range that got replaced. - :param str text: The new text of the range/document. - """ - self.range = range - self.rangeLength = rangeLength - self.text = text + :param Range range: The range of the document that changed. + :param int rangeLength: The length of the range that got replaced. + :param str text: The new text of the range/document. + """ + range: Range + rangeLength: int + text: str -class TextDocumentPositionParams(object): +class TextDocumentPositionParams(BaseModel): """ A parameter literal used in requests to pass a text document and a position inside that document. + Constructs a new TextDocumentPositionParams instance. + + :param TextDocumentIdentifier textDocument: The text document. + :param Position position: The position inside the text document. """ - def __init__(self, textDocument, position): - """ - Constructs a new TextDocumentPositionParams instance. - - :param TextDocumentIdentifier textDocument: The text document. - :param Position position: The position inside the text document. - """ - self.textDocument = textDocument - self.position = position + textDocument: TextDocumentIdentifier + Position: Position -class ParameterInformation(object): +class ParameterInformation(BaseModel): """ Represents a parameter of a callable-signature. A parameter can have a label and a doc-comment. - """ - def __init__(self, label, documentation=""): - """ - Constructs a new ParameterInformation instance. + Constructs a new ParameterInformation instance. - :param str label: The label of this parameter. Will be shown in the UI. - :param str documentation: The human-readable doc-comment of this parameter. Will be shown in the UI but can be omitted. - """ - self.label = label - self.documentation = documentation + :param str label: The label of this parameter. Will be shown in the UI. + :param str documentation: The human-readable doc-comment of this parameter. Will be shown in the UI but can be omitted. + """ + label: str + documentation: str -class SignatureInformation(object): +class SignatureInformation(BaseModel): """ Represents the signature of something callable. A signature can have a label, like a function-name, a doc-comment, and a set of parameters. - """ - def __init__(self, label, documentation="", parameters=[]): - """ - Constructs a new SignatureInformation instance. + Constructs a new SignatureInformation instance. - :param str label: The label of this signature. Will be shown in the UI. - :param str documentation: The human-readable doc-comment of this signature. Will be shown in the UI but can be omitted. - :param ParameterInformation[] parameters: The parameters of this signature. - """ - self.label = label - self.documentation = documentation - self.parameters = [to_type(parameter, ParameterInformation) for parameter in parameters] + :param str label: The label of this signature. Will be shown in the UI. + :param str documentation: The human-readable doc-comment of this signature. Will be shown in the UI but can be omitted. + :param ParameterInformation[] parameters: The parameters of this signature. + """ + label: str + documentation: Optional[str] = '' + parameters: List[ParameterInformation] = [] -class SignatureHelp(object): +class SignatureHelp(BaseModel): """ Signature help represents the signature of something callable. There can be multiple signature but only one active and only one active parameter. - """ - def __init__(self, signatures, activeSignature=0, activeParameter=0): - """ - Constructs a new SignatureHelp instance. + Constructs a new SignatureHelp instance. - :param SignatureInformation[] signatures: One or more signatures. - :param int activeSignature: - :param int activeParameter: - """ - self.signatures = [to_type(signature, SignatureInformation) for signature in signatures] - self.activeSignature = activeSignature - self.activeParameter = activeParameter + :param SignatureInformation[] signatures: One or more signatures. + :param int activeSignature: + :param int activeParameter: + """ + activeSignature: Optional[int] = 0 + activeParameter: Optional[int] = 0 + signatures: List[SignatureInformation] class CompletionTriggerKind(object): - Invoked = 1 - TriggerCharacter = 2 - TriggerForIncompleteCompletions = 3 + Invoked: int = 1 + TriggerCharacter: int = 2 + TriggerForIncompleteCompletions: int = 3 - -class CompletionContext(object): +class CompletionContext(BaseModel): """ Contains additional information about the context in which a completion request is triggered. - """ - def __init__(self, triggerKind, triggerCharacter=None): - """ - Constructs a new CompletionContext instance. + Constructs a new CompletionContext instance. - :param CompletionTriggerKind triggerKind: How the completion was triggered. - :param str triggerCharacter: The trigger character (a single character) that has trigger code complete. - Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` - """ - self.triggerKind = triggerKind - if triggerCharacter: - self.triggerCharacter = triggerCharacter - - -class TextEdit(object): + :param CompletionTriggerKind triggerKind: How the completion was triggered. + :param str triggerCharacter: The trigger character (a single character) that has trigger code complete. + Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` + """ + model_config = ConfigDict(extra='allow') + triggerKind: int + def __init__(self, **data): + for k in data.keys(): + if k == "triggerCharacter": + curr_val = data.get(k) + # if value for triggerCharacter is None or non string + # then ensure attribute doesnt exist in the object + if curr_val is None and not isinstance(curr_val, str): + data.pop(k) + elif k not in self.__class__.model_fields.keys(): + data.pop(k) + super().__init__(**data) + + +class TextEdit(BaseModel): """ A textual edit applicable to a text document. + :param Range range: The range of the text document to be manipulated. To insert + text into a document create a range where start === end. + :param str newText: The string to be inserted. For delete operations use an empty string. """ - def __init__(self, range, newText): - """ - :param Range range: The range of the text document to be manipulated. To insert - text into a document create a range where start === end. - :param str newText: The string to be inserted. For delete operations use an empty string. - """ - self.range = range - self.newText = newText - + range: Range + newText: str class InsertTextFormat(object): - PlainText = 1 - Snippet = 2 - - -class CompletionItem(object): - """ - """ - def __init__(self, label, kind=None, detail=None, documentation=None, deprecated=None, preselect=None, sortText=None, filterText=None, insertText=None, insertTextFormat=None, textEdit=None, additionalTextEdits=None, commitCharacters=None, command=None, data=None, score=0.0): - """ - :param str label: The label of this completion item. By default also the text that is inserted when selecting - this completion. - :param int kind: The kind of this completion item. Based of the kind an icon is chosen by the editor. - :param str detail: A human-readable string with additional information about this item, like type or symbol information. - :param tr ocumentation: A human-readable string that represents a doc-comment. - :param bool deprecated: Indicates if this item is deprecated. - :param bool preselect: Select this item when showing. Note: that only one completion item can be selected and that the - tool / client decides which item that is. The rule is that the first item of those that match best is selected. - :param str sortText: A string that should be used when comparing this item with other items. When `falsy` the label is used. - :param str filterText: A string that should be used when filtering a set of completion items. When `falsy` the label is used. - :param str insertText: A string that should be inserted into a document when selecting this completion. When `falsy` the label is used. - The `insertText` is subject to interpretation by the client side. Some tools might not take the string literally. For example - VS Code when code complete is requested in this example `con` and a completion item with an `insertText` of `console` is provided it - will only insert `sole`. Therefore it is recommended to use `textEdit` instead since it avoids additional client side interpretation. - @deprecated Use textEdit instead. - :param InsertTextFormat insertTextFormat: The format of the insert text. The format applies to both the `insertText` property - and the `newText` property of a provided `textEdit`. - :param TextEdit textEdit: An edit which is applied to a document when selecting this completion. When an edit is provided the value of `insertText` is ignored. - Note:* The range of the edit must be a single line range and it must contain the position at which completion - has been requested. - :param TextEdit additionalTextEdits: An optional array of additional text edits that are applied when selecting this completion. - Edits must not overlap (including the same insert position) with the main edit nor with themselves. - Additional text edits should be used to change text unrelated to the current cursor position - (for example adding an import statement at the top of the file if the completion item will - insert an unqualified type). - :param str commitCharacters: An optional set of characters that when pressed while this completion is active will accept it first and - then type that character. *Note* that all commit characters should have `length=1` and that superfluous - characters will be ignored. - :param Command command: An optional command that is executed *after* inserting this completion. Note: that - additional modifications to the current document should be described with the additionalTextEdits-property. - :param data: An data entry field that is preserved on a completion item between a completion and a completion resolve request. - :param float score: Score of the code completion item. - """ - self.label = label - self.kind = kind - self.detail = detail - self.documentation = documentation - self.deprecated = deprecated - self.preselect = preselect - self.sortText = sortText - self.filterText = filterText - self.insertText = insertText - self.insertTextFormat = insertTextFormat - self.textEdit = textEdit - self.additionalTextEdits = additionalTextEdits - self.commitCharacters = commitCharacters - self.command = command - self.data = data - self.score = score + PlainText: int = 1 + Snippet: int = 2 + +class CompletionItem(BaseModel): + label: str + kind: Optional[int] = None + detail: Optional[str] = None + documentation: Optional[str] = None + deprecated: Optional[bool] = None + preselect: Optional[bool] = None + sortText: Optional[str] = None + filterText: Optional[str] = None + insertText: Optional[str] = None + insertTextFormat: Optional[int] = None + textEdit: Optional[TextEdit] = None + additionalTextEdits: Optional[TextEdit] = None + commitCharacters: Optional[str] = None + command: Optional[Command] = None + data: Optional[Any] = None + score: float = 0.0 class CompletionItemKind(enum.Enum): @@ -396,19 +326,16 @@ class CompletionItemKind(enum.Enum): TypeParameter = 25 -class CompletionList(object): +class CompletionList(BaseModel): """ Represents a collection of [completion items](#CompletionItem) to be presented in the editor. + Constructs a new CompletionContext instance. + :param bool isIncomplete: This list it not complete. Further typing should result in recomputing this list. + :param CompletionItem items: The completion items. """ - def __init__(self, isIncomplete, items): - """ - Constructs a new CompletionContext instance. - - :param bool isIncomplete: This list it not complete. Further typing should result in recomputing this list. - :param CompletionItem items: The completion items. - """ - self.isIncomplete = isIncomplete - self.items = [to_type(i, CompletionItem) for i in items] + isIncomplete: bool + items: List[CompletionItem] + class ErrorCodes(enum.Enum): # Defined by JSON RPC diff --git a/tests/test_pylsp_integration.py b/tests/test_pylsp_integration.py index 261abfb..bd5c9ae 100644 --- a/tests/test_pylsp_integration.py +++ b/tests/test_pylsp_integration.py @@ -96,7 +96,7 @@ def test_type_definition(lsp_client: pylspclient.LspClient): text = open(relative_file_path, "r").read() languageId = LanguageIdentifier.PYTHON version = 1 - # First need to open the file, and then iterate over the docuemnt's symbols + # First need to open the file, and then iterate over the document's symbols symbols = lsp_client.documentSymbol(TextDocumentIdentifier(uri=uri)) assert set(symbol.name for symbol in symbols) == set([]) lsp_client.didOpen(TextDocumentItem(uri=uri, languageId=languageId, version=version, text=text))