diff --git a/src/typecode/contenttype.py b/src/typecode/contenttype.py index f23094b..7c2316a 100644 --- a/src/typecode/contenttype.py +++ b/src/typecode/contenttype.py @@ -205,6 +205,12 @@ class Type(object): "is_filesystem", "is_java_class", "is_java_source", + "is_julia_source", + "is_python_source", + "is_javascript_source", + "is_cpp_source", + "is_rust_source", + "is_go_source", "is_media", "is_media_with_meta", "is_office_doc", @@ -742,7 +748,18 @@ def is_source(self): elif self.is_makefile or self.is_js_map: return False - elif self.is_java_source is True or self.is_c_source is True: + # Recognize "known-by-extension" source types + elif ( + self.is_java_source or + self.is_c_source or + self.is_julia_source or + self.is_python_source or + self.is_javascript_source or + self.is_cpp_source or + self.is_rust_source or + self.is_go_source + + ): return True elif self.filetype_pygment or self.is_script is True: @@ -758,9 +775,39 @@ def programming_language(self): string. """ if self.is_source: + # If the custom extension check found Julia, use that name explicitly + if self.is_julia_source: + return "Julia" return self.filetype_pygment or "" return "" + @property + def is_julia_source(self): + """ + Return True if the file is Julia source code based on .jl extension. + """ + return self.is_file and self.location.lower().endswith(".jl") + + @property + def is_python_source(self): + return self.is_file and self.file_name.lower().endswith(('.py', '.pyw')) + + @property + def is_javascript_source(self): + return self.is_file and self.file_name.lower().endswith(('.js', '.mjs')) + + @property + def is_cpp_source(self): + return self.is_file and self.file_name.lower().endswith(('.cpp', '.cc', '.cxx', '.hpp')) + + @property + def is_rust_source(self): + return self.is_file and self.file_name.lower().endswith('.rs') + + @property + def is_go_source(self): + return self.is_file and self.file_name.lower().endswith('.go') + @property def is_c_source(self): C_EXTENSIONS = set( @@ -950,7 +997,8 @@ def get_text_file_start(location, length=4096): with open(location, "rb") as f: content = text.as_unicode(f.read(length)) finally: - return content + pass + return content def get_filetype(location): diff --git a/tests/test_contenttype.py b/tests/test_contenttype.py index 07fefba..f293b45 100644 --- a/tests/test_contenttype.py +++ b/tests/test_contenttype.py @@ -238,6 +238,17 @@ def test_compiled_elf_so_2(self): assert get_filetype(test_file) in expected assert get_filetype_pygment(test_file) == "" + def test_programming_language_detection_for_julia(self): + # Create a temporary julia file + test_file = self.get_temp_file("test.jl") + with open(test_file, "w") as f: + f.write('println("Hello Julia")') + + # Get the type and check identification + T = get_type(test_file) + assert is_source(test_file) + assert T.programming_language == "Julia" + @pytest.mark.xfail( on_mac or on_windows, reason="Somehow we get really weird results on macOS with libmagic 5.38 and mac, win32 on libmagic 5.39: " @@ -407,3 +418,23 @@ def test_size(self): test_dir = self.get_test_loc("contenttype/size") result = size(test_dir) assert result == 18 + + def test_contenttype_language_attributes_exist(self): + from typecode.contenttype import get_type + + # Get a Type object to test against using this exact test script + test_type = get_type(__file__) + + expected_language_attributes = [ + 'is_c_source', + 'is_java_source', + 'is_julia_source', + 'is_python_source', + 'is_javascript_source', + 'is_cpp_source', + 'is_rust_source', + 'is_go_source' + ] + + for attr_name in expected_language_attributes: + assert hasattr(test_type, attr_name), f"ContentType is missing the expected attribute: {attr_name}"