Skip to content

Commit 6774b85

Browse files
committed
Delay rpy2 import until the formatter is requested
1 parent 3b7e78d commit 6774b85

File tree

1 file changed

+27
-32
lines changed

1 file changed

+27
-32
lines changed

jupyterlab_code_formatter/formatters.py

+27-32
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,11 @@
99
from functools import wraps
1010
from typing import List, Type
1111

12-
try:
13-
import rpy2
14-
import rpy2.robjects
15-
except ImportError:
16-
pass
1712
if sys.version_info >= (3, 9):
1813
from functools import cache
1914
else:
2015
from functools import lru_cache
16+
2117
cache = lru_cache(maxsize=None)
2218

2319
from packaging import version
@@ -357,56 +353,55 @@ def format_code(self, code: str, notebook: bool, **options) -> str:
357353
return isort.code(code=code, **options)
358354

359355

360-
class FormatRFormatter(BaseFormatter):
361-
label = "Apply FormatR Formatter"
362-
package_name = "formatR"
356+
class RFormatter(BaseFormatter):
357+
@property
358+
@abc.abstractmethod
359+
def package_name(self) -> str:
360+
pass
363361

364362
@property
365363
def importable(self) -> bool:
366-
try:
367-
import rpy2.robjects.packages as rpackages
364+
package_location = subprocess.run(
365+
["Rscript", "-e", f"cat(system.file(package='{self.package_name}'))"],
366+
capture_output=True,
367+
text=True,
368+
)
369+
return package_location != ""
368370

369-
rpackages.importr(self.package_name, robject_translations={".env": "env"})
370371

371-
return True
372-
except Exception:
373-
return False
372+
class FormatRFormatter(RFormatter):
373+
label = "Apply FormatR Formatter"
374+
package_name = "formatR"
374375

375376
@handle_line_ending_and_magic
376377
def format_code(self, code: str, notebook: bool, **options) -> str:
377378
import rpy2.robjects.packages as rpackages
379+
from rpy2.robjects import conversion, default_converter
378380

379-
format_r = rpackages.importr(self.package_name, robject_translations={".env": "env"})
380-
formatted_code = format_r.tidy_source(text=code, output=False, **options)
381-
return "\n".join(formatted_code[0])
381+
with conversion.localconverter(default_converter):
382+
format_r = rpackages.importr(self.package_name, robject_translations={".env": "env"})
383+
formatted_code = format_r.tidy_source(text=code, output=False, **options)
384+
return "\n".join(formatted_code[0])
382385

383386

384-
class StylerFormatter(BaseFormatter):
387+
class StylerFormatter(RFormatter):
385388
label = "Apply Styler Formatter"
386389
package_name = "styler"
387390

388-
@property
389-
def importable(self) -> bool:
390-
try:
391-
import rpy2.robjects.packages as rpackages
392-
393-
rpackages.importr(self.package_name)
394-
395-
return True
396-
except Exception:
397-
return False
398-
399391
@handle_line_ending_and_magic
400392
def format_code(self, code: str, notebook: bool, **options) -> str:
401393
import rpy2.robjects.packages as rpackages
394+
from rpy2.robjects import conversion, default_converter
402395

403-
styler_r = rpackages.importr(self.package_name)
404-
formatted_code = styler_r.style_text(code, **self._transform_options(styler_r, options))
405-
return "\n".join(formatted_code)
396+
with conversion.localconverter(default_converter):
397+
styler_r = rpackages.importr(self.package_name)
398+
formatted_code = styler_r.style_text(code, **self._transform_options(styler_r, options))
399+
return "\n".join(formatted_code)
406400

407401
@staticmethod
408402
def _transform_options(styler_r, options):
409403
transformed_options = copy.deepcopy(options)
404+
import rpy2.robjects
410405

411406
if "math_token_spacing" in transformed_options:
412407
if isinstance(options["math_token_spacing"], dict):

0 commit comments

Comments
 (0)