diff --git a/.gitignore b/.gitignore index 92db505..a198702 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,38 @@ -# precompiled python +# Python bytecode *.pyc +__pycache__/ +*.py[cod] +*$py.class -# setuptools/pip stuff +# Virtual environments +venv/ +env/ +ENV/ +.venv/ + +# Build artifacts build/ dist/ *.egg-info/ -*.egg/ +.eggs/ +*.egg + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ -# brlcad output file -*.g +# OS +.DS_Store +Thumbs.db -# editor swap files -.*.sw* +# Testing +.pytest_cache/ +.coverage +htmlcov/ +.tox/ -# intellij pycharm project directory: -.idea +# Distribution +MANIFEST diff --git a/brlcad/ctypes_adaptors.py b/brlcad/ctypes_adaptors.py index 9167ca0..a345002 100644 --- a/brlcad/ctypes_adaptors.py +++ b/brlcad/ctypes_adaptors.py @@ -159,7 +159,7 @@ def plane_from_pointer(t): def transform_from_pointer(t): - return [t[x] for x in xrange(0, 16)] + return [t[x] for x in range(0, 16)] def array2d_from_pointer(t, num_rows, num_cols): diff --git a/brlcad/ged.py b/brlcad/ged.py index b2c7198..9bd26bf 100644 --- a/brlcad/ged.py +++ b/brlcad/ged.py @@ -129,7 +129,7 @@ def execute_command(self, ged_function, *args, **kwargs): if not (result & libged.GED_MORE): break prompt = self._ged_pointer.contents.ged_result_str.contents.vls_str - new_input = raw_input(prompt) + new_input = input(prompt) args.extend(new_input.split()) if readline: # this code collapses the multiple history items resulting from @@ -155,7 +155,7 @@ def execute_command(self, ged_function, *args, **kwargs): else: ged_output = self._ged_pointer.contents.ged_result_str.contents.vls_str if ged_output: - print ged_output + print(ged_output) return result @ged_command diff --git a/brlcad/install/options.py b/brlcad/install/options.py index 61d5d18..7866994 100644 --- a/brlcad/install/options.py +++ b/brlcad/install/options.py @@ -8,10 +8,10 @@ import copy import re import subprocess -import ctypesgencore +import ctypesgen.options as ctypesgencore_options from distutils.version import StrictVersion -from ConfigParser import ConfigParser +from configparser import ConfigParser class SetupException(Exception): @@ -246,7 +246,7 @@ def setup_libraries(bindings_path, config, settings, brlcad_info, logger): """ Read and expand the library list configured in options. """ - default_options = ctypesgencore.options.get_default_options() + default_options = ctypesgencore_options.get_default_options() default_options.include_symbols = None default_options.exclude_symbols = None default_options.output_language = "python" @@ -293,7 +293,7 @@ def setup_libraries(bindings_path, config, settings, brlcad_info, logger): options.output = os.path.join(bindings_path, "{0}.py".format(lib_name)) lib_path = find_shared_lib_file([bin_dir, lib_dir], lib_name) options.libraries = [norm_win_path(lib_path)] - for i in xrange(0, len(lib_headers)): + for i in range(0, len(lib_headers)): lib_headers[i] = os.path.join(include_dir, "brlcad", lib_headers[i]) if not os.access(lib_headers[i], os.R_OK): raise SetupException("Missing header file: {0}".format(lib_headers[i])) diff --git a/brlcad/install/post_install.py b/brlcad/install/post_install.py index 8436b01..a61fa19 100644 --- a/brlcad/install/post_install.py +++ b/brlcad/install/post_install.py @@ -13,12 +13,15 @@ import os import json import logging -import imp +import importlib.util import shutil -import ctypesgencore +import ctypesgen.parser as ctypesgencore_parser +import ctypesgen.processor as ctypesgencore_processor +import ctypesgen.printer_python as ctypesgencore_printer_python +import ctypesgen -from options import load_ctypesgen_options, load_config +from .options import load_ctypesgen_options, load_config def setup_logging(level=logging.DEBUG): @@ -48,15 +51,15 @@ def generate_wrapper(ctypesgen_options, logger): """ # parse logger.debug("parsing") - descriptions = ctypesgencore.parser.parse(ctypesgen_options.headers, ctypesgen_options) + descriptions = ctypesgencore_parser.parse(ctypesgen_options.headers, ctypesgen_options) # process logger.debug("processing") - ctypesgencore.processor.process(descriptions, ctypesgen_options) + ctypesgencore_processor.process(descriptions, ctypesgen_options) # print logger.debug("printing") - ctypesgencore.printer_python.WrapperPrinter(ctypesgen_options.output, ctypesgen_options, descriptions) + ctypesgencore_printer_python.WrapperPrinter(ctypesgen_options.output, ctypesgen_options, descriptions) def cleanup_bindings_dir(bindings_path, cached_bindings_path, logger): @@ -97,7 +100,7 @@ def main(library_path, logger=None): if not logger: logger = setup_logging() - logger.debug("ctypesgencore version is {0}".format(ctypesgencore.__version__)) + logger.debug("ctypesgen version is {0}".format(ctypesgen.__version__)) # this is where the generated files are placed bindings_path = os.path.join(library_path, "_bindings") @@ -172,10 +175,14 @@ def main(library_path, logger=None): # 2) load the latest generated module logger.debug("Loading the __init__.py module from {0}".format(bindings_path)) - imp.load_source("_bindings", os.path.join(bindings_path, "__init__.py")) + spec = importlib.util.spec_from_file_location("_bindings", os.path.join(bindings_path, "__init__.py")) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) logger.debug("Loading the {0} module from {1}.".format(lib_name, ctypesgen_options.output)) - latest_module = imp.load_source(lib_name, ctypesgen_options.output) + spec = importlib.util.spec_from_file_location(lib_name, ctypesgen_options.output) + latest_module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(latest_module) symbols = dir(latest_module) # 3) store the list of defined names from that module by running dir(loaded_module) diff --git a/brlcad/primitives/bot.py b/brlcad/primitives/bot.py index 2e84b08..c83aa43 100644 --- a/brlcad/primitives/bot.py +++ b/brlcad/primitives/bot.py @@ -23,7 +23,7 @@ def __init__(self, bot, vertices, index=None, copy=False): if index==None: if len(vertices)==3: self.index=[] - for i in xrange(0, len(self._points)): + for i in range(0, len(self._points)): self.index.append(bot.vertex_index(self._points[i])) else: raise BRLCADException("A face requires 3 vertices") @@ -87,7 +87,7 @@ def __init__(self, name, mode=1, orientation=1, flags=0, vertices=None, faces=No elif not isinstance(faces, list): curves = list(faces) self.faces = faces - for i in xrange(0, len(faces)): + for i in range(0, len(faces)): self.add_face(faces[i]) def __repr__(self): @@ -142,7 +142,7 @@ def vertex_index(self, value, copy=False): value = Vector(value, copy=copy) if len(value) != 3: raise ValueError("A traingle needs 3D vertexes, but got: {}".format(value)) - for i in xrange(0, vertex_count): + for i in range(0, vertex_count): if self.vertices[i].is_same(value): return i self.vertices.append(value) diff --git a/brlcad/primitives/combination.py b/brlcad/primitives/combination.py index 05f269c..6f45a5c 100644 --- a/brlcad/primitives/combination.py +++ b/brlcad/primitives/combination.py @@ -184,9 +184,9 @@ def __new__(cls, arg): else: arg = [leaf(x) for x in arg] # if any of the children is of the same class, it will accumulate the new nodes: - for i in xrange(0, len(arg)): + for i in range(0, len(arg)): if isinstance(arg[i], cls): - for j in xrange(0, len(arg)): + for j in range(0, len(arg)): if i != j: arg[i].add_child(arg[j]) return arg[i] @@ -232,7 +232,7 @@ def is_same(self, other): return False if len(self.children) != len(other.children): return False - return all([self.children[i].is_same(other.children[i]) for i in xrange(0, len(self.children))]) + return all([self.children[i].is_same(other.children[i]) for i in range(0, len(self.children))]) def build_tree(self, subset=None): if subset and len(subset) == 1: diff --git a/brlcad/primitives/metaball.py b/brlcad/primitives/metaball.py index faf7fe8..6546945 100644 --- a/brlcad/primitives/metaball.py +++ b/brlcad/primitives/metaball.py @@ -97,7 +97,7 @@ class Metaball(Primitive): def __init__(self, name, threshold=1, method=2, points=(((1, 1, 1), 1, 0), ((0, 0, 1), 2, 0)), copy=False): Primitive.__init__(self, name=name) if isinstance(points, list) and not copy: - for i in xrange(0, len(points)): + for i in range(0, len(points)): points[i] = MetaballCtrlPoint(points[i]) else: points = [MetaballCtrlPoint(point, copy=copy) for point in points] diff --git a/brlcad/primitives/pipe.py b/brlcad/primitives/pipe.py index f83cb9a..7ca9de8 100644 --- a/brlcad/primitives/pipe.py +++ b/brlcad/primitives/pipe.py @@ -93,7 +93,7 @@ class Pipe(Primitive): def __init__(self, name, points=(((0, 0, 0), 0.5, 0.3, 1), ((0, 0, 1), 0.5, 0.3, 1)), copy=False): Primitive.__init__(self, name=name) if isinstance(points, list) and not copy: - for i in xrange(0, len(points)): + for i in range(0, len(points)): points[i] = PipePoint(points[i]) else: points = [PipePoint(point, copy=copy) for point in points] @@ -123,7 +123,7 @@ def append_point(self, point, *args, **kwargs): def from_wdb(name, data): points = [] crt_head = data.pipe_segs_head.forw - for i in xrange(0, data.pipe_count): + for i in range(0, data.pipe_count): crt_point = ctypes.cast(crt_head, ctypes.POINTER(librt.wdb_pipept)).contents crt_head = crt_point.l.forw points.append(( diff --git a/brlcad/primitives/sketch.py b/brlcad/primitives/sketch.py index a349c75..5458082 100644 --- a/brlcad/primitives/sketch.py +++ b/brlcad/primitives/sketch.py @@ -56,7 +56,7 @@ class Curve(collections.MutableSequence): def __init__(self, sketch, points, reverse=False, copy=False): self.sketch = sketch self._points = list(points) if copy or not isinstance(points, list) else points - for i in xrange(0, len(self._points)): + for i in range(0, len(self._points)): self._points[i] = sketch.vertex_index(self._points[i]) self.reverse = reverse @@ -252,7 +252,7 @@ def from_wdb(sketch, data, reverse): data = librt.cast(data, librt.POINTER(librt.struct_nurb_seg)).contents point_type = (data.pt_type >> 1) & 0x0f if bool(data.pt_type & 1): - weights = [data.weights[i] for i in xrange(0, data.c_size)] + weights = [data.weights[i] for i in range(0, data.c_size)] coordinate_count = 3 else: weights = None @@ -263,11 +263,11 @@ def from_wdb(sketch, data, reverse): ) result = NURB( sketch, - points=[data.ctl_points[i] for i in xrange(0, data.c_size)], + points=[data.ctl_points[i] for i in range(0, data.c_size)], reverse=reverse, order=data.order, point_type=point_type, - knot_vector=[data.k.knots[i] for i in xrange(0, data.k.k_size)], + knot_vector=[data.k.knots[i] for i in range(0, data.k.k_size)], weights=weights ) return result @@ -337,7 +337,7 @@ def from_wdb(sketch, data, reverse): data = librt.cast(data, librt.POINTER(librt.struct_bezier_seg)).contents return Bezier( sketch, - points=[data.ctl_points[i] for i in xrange(0, data.degree + 1)], + points=[data.ctl_points[i] for i in range(0, data.degree + 1)], reverse=reverse ) @@ -382,7 +382,7 @@ def __init__(self, name, base=(0, 0, 0), u_vec=(1, 0, 0), v_vec=(0, 1, 0), verti elif not isinstance(curves, list): curves = list(curves) self.curves = curves - for i in xrange(0, len(curves)): + for i in range(0, len(curves)): self.add_curve_segment(curves[i], segment_index=i, copy=copy) def __repr__(self): @@ -399,7 +399,7 @@ def vertex_index(self, value, copy=False): value = Vector(value, copy=copy) if len(value) != 2: raise ValueError("Sketches need 2D vertexes, but got: {}".format(value)) - for i in xrange(0, vertex_count): + for i in range(0, vertex_count): if self.vertices[i].is_same(value): return i self.vertices.append(value) @@ -467,7 +467,7 @@ def build_curves(self): else: ci.reverse = None ci.segment = None - for i in xrange(0, ci.count): + for i in range(0, ci.count): curve = self.curves[i] ci.reverse[i] = bool(curve.reverse) ci.segment[i] = librt.cast(librt.pointer(curve.build_segment()), librt.c_void_p) @@ -485,7 +485,7 @@ def has_same_data(self, other): curve_count = len(self.curves) if len(other.curves) != curve_count: return False - return all([self.curves[i].is_same(other.curves[i]) for i in xrange(0, curve_count)]) + return all([self.curves[i].is_same(other.curves[i]) for i in range(0, curve_count)]) def line(self, start, end, reverse=False, copy=False): return Line(self, [start, end], reverse=reverse, copy=copy) @@ -517,13 +517,13 @@ def revolve(self, name, revolve_center=None, revolve_axis=None, radius=None, ang @staticmethod def from_wdb(name, data): vertices = [] - for i in xrange(0, data.vert_count): + for i in range(0, data.vert_count): vertices.append(Vector(data.verts[i])) result = Sketch( name=name, base=Vector(data.V), u_vec=Vector(data.u_vec), v_vec=Vector(data.v_vec), vertices=vertices ) curves = data.curve - for i in xrange(0, curves.count): + for i in range(0, curves.count): curve = curves.segment[i] magic = librt.cast(curve, librt.POINTER(librt.struct_line_seg)).contents.magic reverse = bool(curves.reverse[i]) diff --git a/brlcad/vmath/vector.py b/brlcad/vmath/vector.py index 6bb9acd..3558880 100644 --- a/brlcad/vmath/vector.py +++ b/brlcad/vmath/vector.py @@ -271,7 +271,7 @@ def compare_for_sort(self, other): result = length - len(other) if result: return result - for i in xrange(0, length): + for i in range(0, length): result = self[i] - other[i] if result: return result diff --git a/brlcad/wdb.py b/brlcad/wdb.py index 7ec3306..09f877c 100644 --- a/brlcad/wdb.py +++ b/brlcad/wdb.py @@ -83,7 +83,7 @@ def __init__(self, db_file, title=None): raise BRLCADException("Can't open DB file <{0}>: {1}".format(db_file, e)) def __iter__(self): - for i in xrange(0, libwdb.RT_DBNHASH): + for i in range(0, libwdb.RT_DBNHASH): dp = self.db_ip.contents.dbi_Head[i] while dp: crt_dir = dp.contents diff --git a/examples/wdb_primitives.py b/examples/wdb_primitives.py index da83f5d..bc5b745 100644 --- a/examples/wdb_primitives.py +++ b/examples/wdb_primitives.py @@ -202,4 +202,4 @@ with WDB("test_wdb.g") as brl_db: for x in brl_db.ls(): - print brl_db.lookup(x) + print(brl_db.lookup(x)) diff --git a/setup.py b/setup.py index 85af912..c6b1576 100644 --- a/setup.py +++ b/setup.py @@ -27,10 +27,23 @@ def run_after(command): import brlcad import brlcad.install.post_install - #library_path = os.path.join(command.install_lib, "brlcad") - #library_path = os.path.abspath(os.path.dirname(brlcad.__file__)) - egg_path = glob.glob(os.path.join(command.install_lib, "brlcad*.egg/"))[0] - library_path = os.path.join(egg_path, "brlcad") + # Try to find the library path in various ways for compatibility + library_path = None + + # Method 1: Try to find egg directory (legacy) + egg_paths = glob.glob(os.path.join(command.install_lib, "brlcad*.egg/")) + if egg_paths: + library_path = os.path.join(egg_paths[0], "brlcad") + + # Method 2: Try direct path in wheel/site-packages + if not library_path or not os.path.isdir(library_path): + direct_path = os.path.join(command.install_lib, "brlcad") + if os.path.isdir(direct_path): + library_path = direct_path + + # Method 3: Use the installed module's path + if not library_path or not os.path.isdir(library_path): + library_path = os.path.abspath(os.path.dirname(brlcad.__file__)) try: brlcad.install.post_install.main(library_path) @@ -117,13 +130,10 @@ class CustomInstallCommand(InstallCommand): ], zip_safe=False, setup_requires=[ - "ctypesgen-dev", + "ctypesgen", ], install_requires=[ - "ctypesgen-dev", - ], - dependency_links=[ - "https://github.com/kanzure/ctypesgen/tarball/short-preamble-setuptools#egg=ctypesgen-dev-0.0.1", + "ctypesgen", ], cmdclass={ "install": CustomInstallCommand, diff --git a/tests/dump_ged_commands.py b/tests/dump_ged_commands.py index 9969f89..5b4527d 100644 --- a/tests/dump_ged_commands.py +++ b/tests/dump_ged_commands.py @@ -6,7 +6,7 @@ ged_names = [x for x in dir(libged) if x.startswith('ged_') and not issubclass(type(getattr(libged, x)), types.TypeType)] -print "Number of entries: ", len(ged_names) +print("Number of entries: ", len(ged_names)) gedh = open(header_file).read() @@ -19,14 +19,14 @@ for match in header_pattern.finditer(gedh): cmd_name = match.group(1) if cmd_name not in ged_names: - print "Command not found: {}".format(cmd_name) + print("Command not found: {}".format(cmd_name)) args_map[cmd_name] = ws_pattern.sub(' ', match.group(2)) for name in ged_names: if name not in args_map: - print "Arguments not found: {}".format(name) + print("Arguments not found: {}".format(name)) -print "#*********** TODO: implement explicit list of params *******************#" +print("#*********** TODO: implement explicit list of params *******************#") for name in ged_names: if name in implemented: @@ -38,13 +38,13 @@ method_name = cmd_name if method_name in globals() or method_name in dir(__builtins__): method_name = 'ged_' + name - print ' @ged_command\n' \ + print(' @ged_command\n' \ ' def {}(self, *args):\n' \ ' return self.execute_command(libged.{}, *args)\n'.format( method_name, name, cmd_name - ) + )) -print "#********************* TODO: wrap params ******************************#" +print("#********************* TODO: wrap params ******************************#") for name in ged_names: if name in implemented: @@ -56,10 +56,10 @@ method_name = cmd_name if method_name in globals() or method_name in dir(__builtins__): method_name = 'ged_' + name - print ' @ged_command\n' \ + print(' @ged_command\n' \ ' def {}(self, *args):\n' \ ' # todo: wrap params: {}\n' \ - ' # return self.execute_command(libged.{}, "{}", *args)\n' \ - ' raise NotImplementedError("Not implemented yet !")\n'.format( + ' # return self.execute_command(libged.{}, \"{}\", *args)\n' \ + ' raise NotImplementedError(\"Not implemented yet !\")\n'.format( method_name, cmd_args, name, cmd_name - ) + )) diff --git a/tests/test_empty_db.py b/tests/test_empty_db.py index d4412ac..c316807 100644 --- a/tests/test_empty_db.py +++ b/tests/test_empty_db.py @@ -5,7 +5,7 @@ def ls(db_ip): - for i in xrange(0, libwdb.RT_DBNHASH): + for i in range(0, libwdb.RT_DBNHASH): dp = db_ip.contents.dbi_Head[i] while dp: crt_dir = dp.contents