1- from codetide . parsers .base_parser import BaseParser
2- from codetide .core .common import readFile
3- from codetide .core .models import (
1+ from .base_parser import BaseParser
2+ from . .core .common import readFile
3+ from . .core .models import (
44 ClassAttribute , ClassDefinition , CodeBase , CodeReference ,
55 FunctionDefinition , FunctionSignature , ImportStatement ,
66 CodeFileModel , MethodDefinition , Parameter , VariableDeclaration
1414from pathlib import Path
1515import asyncio
1616import re
17-
17+ import os
1818class PythonParser (BaseParser ):
1919 """
2020 Python-specific implementation of the BaseParser using tree-sitter.
@@ -133,15 +133,48 @@ def _process_node(cls, node: Node, code: bytes, codeFile :CodeFileModel):
133133 # elif child.type == "assignment": # <- class attribute
134134 # cls._process_assignment(child, code, codeFile)
135135
136+ @staticmethod
137+ def _rebuild_source_from_relative (relative_import_source :str , relative_import_name :str , filepath :str )-> str :
138+ relative_location_index = relative_import_source .count ("." )
139+ source_location = Path (filepath ).parent
140+ for _ in range (1 , relative_location_index ):
141+ source_location = Path (source_location ).parent
142+ source_id = str (source_location ).replace (os .path .sep , "." )
143+ return f"{ source_id } .{ relative_import_name } "
144+
145+ @classmethod
146+ def _process_relative_import_node (cls , node : Node , code : bytes , codeFile :CodeFileModel ):
147+ print ("inside" )
148+ source = None
149+ relative_import_source = None
150+ relative_import_name = None
151+ for child in node .children :
152+ if child .type == "import_prefix" :
153+ relative_import_source = cls ._get_content (code , child )
154+ elif child .type == "dotted_name" :
155+ relative_import_name = cls ._get_content (code , child )
156+ if relative_import_source and relative_import_name :
157+ source = cls ._rebuild_source_from_relative (
158+ relative_import_source = relative_import_source ,
159+ relative_import_name = relative_import_name ,
160+ filepath = codeFile .file_path
161+ )
162+ print (f"{ source = } \n " )
163+ return source
164+
136165 @classmethod
137166 def _process_import_node (cls , node : Node , code : bytes , codeFile :CodeFileModel ):
138167 source = None
139168 next_is_from_import = False
140169 next_is_import = False
170+ is_relative = False
141171 for child in node .children :
142172 if child .type == "from" :
143173 next_is_from_import = True
144- elif child .type == "dotted_name" and next_is_from_import :
174+ elif child .type == "relative_import" :
175+ source = cls ._process_relative_import_node (child , code , codeFile )
176+ is_relative = True
177+ elif child .type == "dotted_name" and next_is_from_import and not is_relative :
145178 next_is_from_import = False
146179 source = cls ._get_content (code , child )
147180 elif child .type == "import" :
@@ -159,6 +192,8 @@ def _process_import_node(cls, node: Node, code: bytes, codeFile :CodeFileModel):
159192 source = source ,
160193 name = name
161194 )
195+ if is_relative :
196+ importStatement .import_type = "relative"
162197 codeFile .add_import (importStatement )
163198 cls ._generate_unique_import_id (codeFile .imports [- 1 ])
164199
@@ -378,6 +413,9 @@ def _default_unique_import_id(cls, importModel :ImportStatement)->str:
378413 def _generate_unique_import_id (cls , importModel :ImportStatement ):
379414 """Generate a unique ID for the function definition"""
380415 unique_id = cls ._default_unique_import_id (importModel )
416+
417+ if unique_id .startswith ("." ):
418+ print (f"{ unique_id = } " )
381419
382420 if "__init__" in importModel .file_path :
383421 # if Path(importModel.file_path).with_suffix("") == Path(importModel.file_path):
0 commit comments