Example #1
0
 def test_custom_pydistutils(self):
     if os.name == 'posix':
         user_filename = '.pydistutils.cfg'
     else:
         user_filename = 'pydistutils.cfg'
     temp_dir = self.mkdtemp()
     user_filename = os.path.join(temp_dir, user_filename)
     f = open(user_filename, 'w')
     try:
         f.write('.')
     finally:
         f.close()
     try:
         dist = Distribution()
         if sys.platform in ('linux', 'darwin'):
             os.environ['HOME'] = temp_dir
             files = dist.find_config_files()
             self.assertIn(user_filename, files)
         if sys.platform == 'win32':
             os.environ['HOME'] = temp_dir
             files = dist.find_config_files()
             self.assertIn(user_filename, files,
                           '%r not found in %r' % (user_filename, files))
     finally:
         os.remove(user_filename)
Example #2
0
    def test_custom_pydistutils(self):
        # fixes #2166
        # make sure pydistutils.cfg is found
        if os.name == 'posix':
            user_filename = ".pydistutils.cfg"
        else:
            user_filename = "pydistutils.cfg"

        temp_dir = self.mkdtemp()
        user_filename = os.path.join(temp_dir, user_filename)
        f = open(user_filename, 'w')
        try:
            f.write('.')
        finally:
            f.close()

        try:
            dist = Distribution()

            # linux-style
            if sys.platform in ('linux', 'darwin'):
                os.environ['HOME'] = temp_dir
                files = dist.find_config_files()
                self.assertIn(user_filename, files)

            # win32-style
            if sys.platform == 'win32':
                # home drive should be found
                os.environ['USERPROFILE'] = temp_dir
                files = dist.find_config_files()
                self.assertIn(user_filename, files,
                              '%r not found in %r' % (user_filename, files))
        finally:
            os.remove(user_filename)
Example #3
0
    def test_find_config_files_disable(self):
        # Ticket #1180: Allow user to disable their home config file.
        temp_home = self.mkdtemp()
        if os.name == 'posix':
            user_filename = os.path.join(temp_home, ".pydistutils.cfg")
        else:
            user_filename = os.path.join(temp_home, "pydistutils.cfg")

        with open(user_filename, 'w') as f:
            f.write('[distutils]\n')

        def _expander(path):
            return temp_home

        old_expander = os.path.expanduser
        os.path.expanduser = _expander
        try:
            d = Distribution()
            all_files = d.find_config_files()

            d = Distribution(attrs={'script_args': ['--no-user-cfg']})
            files = d.find_config_files()
        finally:
            os.path.expanduser = old_expander

        # make sure --no-user-cfg disables the user cfg file
        self.assertEqual(len(all_files)-1, len(files))
Example #4
0
    def test_custom_pydistutils(self):
        # fixes #2166
        # make sure pydistutils.cfg is found
        if os.name == 'posix':
            user_filename = ".pydistutils.cfg"
        else:
            user_filename = "pydistutils.cfg"

        temp_dir = self.mkdtemp()
        user_filename = os.path.join(temp_dir, user_filename)
        f = open(user_filename, 'w')
        try:
            f.write('.')
        finally:
            f.close()

        try:
            dist = Distribution()

            # linux-style
            if sys.platform in ('linux', 'darwin'):
                os.environ['HOME'] = temp_dir
                files = dist.find_config_files()
                self.assertIn(user_filename, files)

            # win32-style
            if sys.platform == 'win32':
                # home drive should be found
                os.environ['HOME'] = temp_dir
                files = dist.find_config_files()
                self.assertIn(user_filename, files,
                              '%r not found in %r' % (user_filename, files))
        finally:
            os.remove(user_filename)
Example #5
0
    def test_find_config_files_disable(self):
        # Ticket #1180: Allow user to disable their home config file.
        temp_home = self.mkdtemp()
        if os.name == 'posix':
            user_filename = os.path.join(temp_home, ".pydistutils.cfg")
        else:
            user_filename = os.path.join(temp_home, "pydistutils.cfg")

        with open(user_filename, 'w') as f:
            f.write('[distutils]\n')

        def _expander(path):
            return temp_home

        old_expander = os.path.expanduser
        os.path.expanduser = _expander
        try:
            d = Distribution()
            all_files = d.find_config_files()

            d = Distribution(attrs={'script_args': ['--no-user-cfg']})
            files = d.find_config_files()
        finally:
            os.path.expanduser = old_expander

        # make sure --no-user-cfg disables the user cfg file
        self.assertEqual(len(all_files) - 1, len(files))
Example #6
0
    def test_custom_pydistutils(self):
        # fixes #2166
        # make sure pydistutils.cfg is found
        if os.name == "posix":
            user_filename = ".pydistutils.cfg"
        else:
            user_filename = "pydistutils.cfg"

        temp_dir = self.mkdtemp()
        user_filename = os.path.join(temp_dir, user_filename)
        f = open(user_filename, "w")
        try:
            f.write(".")
        finally:
            f.close()

        try:
            dist = Distribution()

            # linux-style
            if sys.platform in ("linux", "darwin"):
                os.environ["HOME"] = temp_dir
                files = dist.find_config_files()
                self.assertIn(user_filename, files)

            # win32-style
            if sys.platform == "win32":
                # home drive should be found
                os.environ["HOME"] = temp_dir
                files = dist.find_config_files()
                self.assertIn(user_filename, files, "%r not found in %r" % (user_filename, files))
        finally:
            os.remove(user_filename)
    def handle(self, *args, **options):
        cmd = ('python setup.py {quiet} extract_messages '
               '-F babel-{domain}.cfg '
               '--input-dirs {module} '
               '-o {potfile}')
        distribution = Distribution()
        distribution.parse_config_files(distribution.find_config_files())

        quiet = '-q' if int(options['verbosity']) == 0 else ''
        if options['check_only']:
            cmd += " ; rm {potfile}"

        for module in options['module']:
            for domain in options['domain']:
                potfile = '{module}/locale/{domain}.pot'.format(module=module,
                                                                domain=domain)
                if not os.path.exists(potfile):
                    with open(potfile, 'wb') as f:
                        f.write(b'')

                call(cmd.format(module=module,
                                domain=domain,
                                potfile=potfile,
                                quiet=quiet),
                     shell=True)
Example #8
0
    def handle_makemessages(self, **options):
        locale_paths = list(settings.LOCALE_PATHS)
        domain = options.pop('domain')
        locales = options.pop('locale')

        # support for mapping file specification via setup.cfg
        # TODO: Try to support all possible options.
        distribution = Distribution()
        distribution.parse_config_files(distribution.find_config_files())

        mapping_file = options.pop('mapping_file', None)
        has_extract = 'extract_messages' in distribution.command_options
        if mapping_file is None and has_extract:
            opts = distribution.command_options['extract_messages']
            try:
                mapping_file = opts['mapping_file'][1]
            except (IndexError, KeyError):
                mapping_file = None

        for path in locale_paths:
            potfile = os.path.join(path, '%s.pot' % domain)

            if not os.path.exists(path):
                os.makedirs(path)

            if not os.path.exists(potfile):
                with open(potfile, 'wb') as fobj:
                    fobj.write(b'')

            cmd = ['pybabel', 'extract', '-o', potfile]

            if mapping_file is not None:
                cmd.extend(['-F', mapping_file])

            cmd.append(os.path.dirname(os.path.relpath(path)))

            call(cmd)

            for locale in locales:
                pofile = os.path.join(
                    os.path.dirname(potfile),
                    locale,
                    'LC_MESSAGES',
                    '%s.po' % domain)

                if not os.path.isdir(os.path.dirname(pofile)):
                    os.makedirs(os.path.dirname(pofile))

                if not os.path.exists(pofile):
                    with open(pofile, 'wb') as fobj:
                        fobj.write(b'')

                cmd = ['pybabel', 'update', '-D', domain,
                       '-i', potfile,
                       '-d', os.path.relpath(path),
                       '-l', locale]
                call(cmd)
Example #9
0
    def handle_makemessages(self, **options):
        locale_paths = list(settings.LOCALE_PATHS)
        domain = options.pop('domain')
        locales = options.pop('locale')

        # support for mapping file specification via setup.cfg
        # TODO: Try to support all possible options.
        distribution = Distribution()
        distribution.parse_config_files(distribution.find_config_files())

        mapping_file = options.pop('mapping_file', None)
        has_extract = 'extract_messages' in distribution.command_options
        if mapping_file is None and has_extract:
            opts = distribution.command_options['extract_messages']
            try:
                mapping_file = opts['mapping_file'][1]
            except (IndexError, KeyError):
                mapping_file = None

        for path in locale_paths:
            potfile = os.path.join(path, '%s.pot' % domain)

            if not os.path.exists(path):
                os.makedirs(path)

            if not os.path.exists(potfile):
                with open(potfile, 'wb') as fobj:
                    fobj.write(b'')

            cmd = ['pybabel', 'extract', '-o', potfile]

            if mapping_file is not None:
                cmd.extend(['-F', mapping_file])

            cmd.append(os.path.dirname(os.path.relpath(path)))

            call(cmd)

            for locale in locales:
                pofile = os.path.join(
                    os.path.dirname(potfile),
                    locale,
                    'LC_MESSAGES',
                    '%s.po' % domain)

                if not os.path.isdir(os.path.dirname(pofile)):
                    os.makedirs(os.path.dirname(pofile))

                if not os.path.exists(pofile):
                    with open(pofile, 'wb') as fobj:
                        fobj.write(b'')

                cmd = ['pybabel', 'update', '-D', domain,
                       '-i', potfile,
                       '-d', os.path.relpath(path),
                       '-l', locale]
                call(cmd)
Example #10
0
def build_so(module_name, sources, setup_args=None):
    from distutils.dist import Distribution
    from distutils.errors import DistutilsArgError
    from distutils.extension import Extension
    from shutil import copy2

    setup_args = generate_setup_args(setup_args)

    dist = Distribution(setup_args)

    ext = Extension(
        name = module_name,
        sources = sources,
        include_dirs = [ find_handsome_include_dir() ],

        extra_compile_args = [ '-std=c++11' ],
    )

    if dist.ext_modules is None:
        dist.ext_modules = [ ext ]
    else:
        dist.ext_modules.append(ext)

    target_dir, _ = os.path.split(os.path.abspath(__file__))

    build = dist.get_command_obj('build')
    build.build_base = os.path.join(target_dir, 'build')

    cfgfiles = dist.find_config_files()
    dist.parse_config_files(cfgfiles)

    try:
        ok = dist.parse_command_line()
    except DistutilsArgError:
        raise

    if not ok:
        raise RuntimeError('Build cannot continue')

    command = dist.get_command_obj("build_ext")
    dist.run_commands()

    so_path = os.path.abspath(command.get_outputs()[0])
    _, so_name = os.path.split(so_path)

    target_path = os.path.join(target_dir, so_name)

    if os.path.isfile(target_path):
        os.unlink(target_path)
    
    copy2(so_path, target_path)

    return target_path
Example #11
0
 def find_config_files(self):
     """Search for additional `setup.cfg` file in source directory."""
     files = _Distribution.find_config_files(self)
     # Handle source-directory setup.cfg
     local_file = "setup.cfg"
     filename = os.path.join(self.srcdir, local_file)
     if os.path.isfile(filename):
         if local_file in files:
             files.insert(-1, filename)
         else:
             files.append(filename)
     return files
Example #12
0
def _read_artifactory_config_section():
    dist = Distribution()
    file_names = dist.find_config_files()
    dist.parse_config_files(filenames=file_names)
    artifactory_config_key = "artifactory"
    artifactory_opts = dist.get_option_dict(artifactory_config_key)

    if not artifactory_opts:
        raise DistutilsOptionError('Could not find a {} section in {}'.format(
            artifactory_config_key, file_names))

    return artifactory_opts
Example #13
0
    def test_find_config_files_disable(self):
        temp_home = self.mkdtemp()
        if os.name == 'posix':
            user_filename = os.path.join(temp_home, '.pydistutils.cfg')
        else:
            user_filename = os.path.join(temp_home, 'pydistutils.cfg')
        with open(user_filename, 'w') as f:
            f.write('[distutils]\n')

        def _expander(path):
            return temp_home

        old_expander = os.path.expanduser
        os.path.expanduser = _expander
        try:
            d = Distribution()
            all_files = d.find_config_files()
            d = Distribution(attrs={'script_args': ['--no-user-cfg']})
            files = d.find_config_files()
        finally:
            os.path.expanduser = old_expander
        self.assertEqual(len(all_files) - 1, len(files))
def _read_artifactory_config_section():
    dist = Distribution()
    file_names = dist.find_config_files()
    dist.parse_config_files(filenames=file_names)
    artifactory_config_key = "artifactory"
    artifactory_opts = dist.get_option_dict(artifactory_config_key)

    if not artifactory_opts:
        raise DistutilsOptionError(
            'Could not find a {} section in {}'.format(
                artifactory_config_key,
                file_names))

    return artifactory_opts
Example #15
0
    def handle(self, *args, **options):
        cmd = ('python setup.py extract_messages -F babel-{domain}.cfg '
               '-o {module}/locale/{domain}.pot')
        distribution = Distribution()
        distribution.parse_config_files(distribution.find_config_files())

        if options['check_only']:
            cmd += " ; rm {module}/locale/{domain}.pot"

        for module in options['module']:
            for domain in options['domain']:
                potfile = '{module}/locale/{domain}.pot'.format(module=module,
                                                                domain=domain)
                if not os.path.exists(potfile):
                    with open(potfile, 'wb') as f:
                        f.write(b'')

                call(cmd.format(module=module, domain=domain, potfile=potfile),
                     shell=True)
Example #16
0
    def handle(self, *args, **options):
        cmd = ('python setup.py extract_messages -F babel-{domain}.cfg '
               '-o {module}/locale/{domain}.pot')
        distribution = Distribution()
        distribution.parse_config_files(distribution.find_config_files())

        if options['check_only']:
            cmd += " ; rm {module}/locale/{domain}.pot"

        for module in options['module']:
            for domain in options['domain']:
                potfile = '{module}/locale/{domain}.pot'.format(module=module,
                                                                domain=domain)
                if not os.path.exists(potfile):
                    with open(potfile, 'wb') as f:
                        f.write(b'')

                call(cmd.format(module=module, domain=domain, potfile=potfile),
                     shell=True)
Example #17
0
def compile_with_distutils(extension_name, 
                              src_filename,
                              extra_objects = [], 
                              extra_compiler_flags = [],
                              extra_link_flags = [],   
                              print_commands = False):

    # copied largely from pyxbuild 
    from distutils.dist import Distribution
    from distutils.extension import Extension
    
    compiler_flags = get_compiler_flags(extra_compiler_flags)
    # don't need -shared in the flags since the default CC on Mac OS 
    # might specify -bundle instead and the two are mutually exclusive
    linker_flags = get_linker_flags(extra_link_flags, shared=False)
    
    ext = Extension(name=extension_name, 
                    sources=[src_filename],
                    include_dirs = include_dirs,  
                    extra_objects=extra_objects,
                    extra_compile_args=compiler_flags,
                    extra_link_args=linker_flags)
  
    script_args = ['build_ext', '--quiet']
    setup_args = {"script_name": None,
                  "script_args": script_args, 
                  }
    dist = Distribution(setup_args)
    if not dist.ext_modules: dist.ext_modules = []
    dist.ext_modules.append(ext)
    # I have no idea how distutils works or why I have to do any of this 
    config_files = dist.find_config_files()
    try: config_files.remove('setup.cfg')
    except ValueError: pass
    dist.parse_config_files(config_files)
    dist.parse_command_line()
    obj_build_ext = dist.get_command_obj("build_ext")
    
    dist.run_commands()
    shared_name = obj_build_ext.get_outputs()[0]
    return shared_name
Example #18
0
    def handle(self, *args, **options):
        cmd = ('python setup.py {quiet} extract_messages '
               '-F babel-{domain}.cfg '
               '--input-dirs {module} '
               '-o {potfile}')
        distribution = Distribution()
        distribution.parse_config_files(distribution.find_config_files())

        quiet = '-q' if int(options['verbosity']) == 0 else ''
        if options['check_only']:
            cmd += " ; rm {potfile}"

        for module in options['module']:
            for domain in options['domain']:
                potfile = '{module}/locale/{domain}.pot'.format(module=module,
                                                                domain=domain)
                if not os.path.exists(potfile):
                    with open(potfile, 'wb') as f:
                        f.write(b'')

                call(cmd.format(module=module, domain=domain, potfile=potfile,
                                quiet=quiet), shell=True)
Example #19
0
def pyx_to_dll(filename,
               ext=None,
               force_rebuild=0,
               build_in_temp=False,
               pyxbuild_dir=None,
               setup_args={},
               reload_support=False):
    """Compile a PYX file to a DLL and return the name of the generated .so 
       or .dll ."""
    assert os.path.exists(
        filename), "Could not find %s" % os.path.abspath(filename)

    path, name = os.path.split(filename)

    if not ext:
        modname, extension = os.path.splitext(name)
        assert extension in (".pyx", ".py"), extension
        if not HAS_CYTHON:
            filename = filename[:-len(extension)] + '.c'
        ext = Extension(name=modname, sources=[filename])

    if not pyxbuild_dir:
        pyxbuild_dir = os.path.join(path, "_pyxbld")

    script_args = setup_args.get("script_args", [])
    if DEBUG or "--verbose" in script_args:
        quiet = "--verbose"
    else:
        quiet = "--quiet"
    args = [quiet, "build_ext"]
    if force_rebuild:
        args.append("--force")
    if HAS_CYTHON and build_in_temp:
        args.append("--pyrex-c-in-temp")
    sargs = setup_args.copy()
    sargs.update({"script_name": None, "script_args": args + script_args})
    dist = Distribution(sargs)
    if not dist.ext_modules:
        dist.ext_modules = []
    dist.ext_modules.append(ext)
    if HAS_CYTHON:
        dist.cmdclass = {'build_ext': build_ext}
    build = dist.get_command_obj('build')
    build.build_base = pyxbuild_dir

    config_files = dist.find_config_files()
    try:
        config_files.remove('setup.cfg')
    except ValueError:
        pass
    dist.parse_config_files(config_files)

    cfgfiles = dist.find_config_files()
    try:
        cfgfiles.remove('setup.cfg')
    except ValueError:
        pass
    dist.parse_config_files(cfgfiles)
    try:
        ok = dist.parse_command_line()
    except DistutilsArgError:
        raise

    if DEBUG:
        print("options (after parsing command line):")
        dist.dump_option_dicts()
    assert ok

    try:
        dist.run_commands()
        obj_build_ext = dist.get_command_obj("build_ext")
        so_path = obj_build_ext.get_outputs()[0]
        if obj_build_ext.inplace:
            # Python distutils get_outputs()[ returns a wrong so_path
            # when --inplace ; see http://bugs.python.org/issue5977
            # workaround:
            so_path = os.path.join(os.path.dirname(filename),
                                   os.path.basename(so_path))
        if reload_support:
            org_path = so_path
            timestamp = os.path.getmtime(org_path)
            global _reloads
            last_timestamp, last_path, count = _reloads.get(
                org_path, (None, None, 0))
            if last_timestamp == timestamp:
                so_path = last_path
            else:
                basename = os.path.basename(org_path)
                while count < 100:
                    count += 1
                    r_path = os.path.join(obj_build_ext.build_lib,
                                          basename + '.reload%s' % count)
                    try:
                        import shutil  # late import / reload_support is: debugging
                        shutil.copy2(org_path, r_path)
                        so_path = r_path
                    except IOError:
                        continue
                    break
                else:
                    # used up all 100 slots
                    raise ImportError("reload count for %s reached maximum" %
                                      org_path)
                _reloads[org_path] = (timestamp, so_path, count)
        return so_path
    except KeyboardInterrupt:
        sys.exit(1)
    except (IOError, os.error):
        exc = sys.exc_info()[1]
        error = grok_environment_error(exc)

        if DEBUG:
            sys.stderr.write(error + "\n")
        raise
Example #20
0
def pyx_to_dll(
    filename, ext=None, force_rebuild=0, build_in_temp=False, pyxbuild_dir=None, setup_args={}, reload_support=False
):
    """Compile a PYX file to a DLL and return the name of the generated .so 
       or .dll ."""
    assert os.path.exists(filename), "Could not find %s" % os.path.abspath(filename)

    path, name = os.path.split(filename)

    if not ext:
        modname, extension = os.path.splitext(name)
        assert extension in (".pyx", ".py"), extension
        if not HAS_CYTHON:
            filename = filename[: -len(extension)] + ".c"
        ext = Extension(name=modname, sources=[filename])

    if not pyxbuild_dir:
        pyxbuild_dir = os.path.join(path, "_pyxbld")

    script_args = setup_args.get("script_args", [])
    if DEBUG or "--verbose" in script_args:
        quiet = "--verbose"
    else:
        quiet = "--quiet"
    args = [quiet, "build_ext"]
    if force_rebuild:
        args.append("--force")
    if HAS_CYTHON and build_in_temp:
        args.append("--pyrex-c-in-temp")
    sargs = setup_args.copy()
    sargs.update({"script_name": None, "script_args": args + script_args})
    dist = Distribution(sargs)
    if not dist.ext_modules:
        dist.ext_modules = []
    dist.ext_modules.append(ext)
    if HAS_CYTHON:
        dist.cmdclass = {"build_ext": build_ext}
    build = dist.get_command_obj("build")
    build.build_base = pyxbuild_dir

    config_files = dist.find_config_files()
    try:
        config_files.remove("setup.cfg")
    except ValueError:
        pass
    dist.parse_config_files(config_files)

    cfgfiles = dist.find_config_files()
    try:
        cfgfiles.remove("setup.cfg")
    except ValueError:
        pass
    dist.parse_config_files(cfgfiles)
    try:
        ok = dist.parse_command_line()
    except DistutilsArgError:
        raise

    if DEBUG:
        print("options (after parsing command line):")
        dist.dump_option_dicts()
    assert ok

    try:
        dist.run_commands()
        obj_build_ext = dist.get_command_obj("build_ext")
        so_path = obj_build_ext.get_outputs()[0]
        if obj_build_ext.inplace:
            # Python distutils get_outputs()[ returns a wrong so_path
            # when --inplace ; see http://bugs.python.org/issue5977
            # workaround:
            so_path = os.path.join(os.path.dirname(filename), os.path.basename(so_path))
        if reload_support:
            org_path = so_path
            timestamp = os.path.getmtime(org_path)
            global _reloads
            last_timestamp, last_path, count = _reloads.get(org_path, (None, None, 0))
            if last_timestamp == timestamp:
                so_path = last_path
            else:
                basename = os.path.basename(org_path)
                while count < 100:
                    count += 1
                    r_path = os.path.join(obj_build_ext.build_lib, basename + ".reload%s" % count)
                    try:
                        import shutil  # late import / reload_support is: debugging

                        shutil.copy2(org_path, r_path)
                        so_path = r_path
                    except IOError:
                        continue
                    break
                else:
                    # used up all 100 slots
                    raise ImportError("reload count for %s reached maximum" % org_path)
                _reloads[org_path] = (timestamp, so_path, count)
        return so_path
    except KeyboardInterrupt:
        sys.exit(1)
    except (IOError, os.error):
        exc = sys.exc_info()[1]
        error = grok_environment_error(exc)

        if DEBUG:
            sys.stderr.write(error + "\n")
        raise
Example #21
0
def pyx_to_dll(filename,
               ext=None,
               force_rebuild=0,
               build_in_temp=False,
               pyxbuild_dir=None,
               setup_args={},
               reload_support=False,
               inplace=False):
    """Compile a PYX file to a DLL and return the name of the generated .so 
       or .dll ."""
    assert os.path.exists(
        filename), "Could not find %s" % os.path.abspath(filename)

    path, name = os.path.split(os.path.abspath(filename))

    if not ext:
        modname, extension = os.path.splitext(name)
        assert extension in (".pyx", ".py"), extension
        if not HAS_CYTHON:
            filename = filename[:-len(extension)] + '.c'
        ext = Extension(name=modname, sources=[filename])

    if not pyxbuild_dir:
        pyxbuild_dir = os.path.join(path, "_pyxbld")

    package_base_dir = path
    for package_name in ext.name.split('.')[-2::-1]:
        package_base_dir, pname = os.path.split(package_base_dir)
        if pname != package_name:
            # something is wrong - package path doesn't match file path
            package_base_dir = None
            break

    script_args = setup_args.get("script_args", [])
    if DEBUG or "--verbose" in script_args:
        quiet = "--verbose"
    else:
        quiet = "--quiet"
    args = [quiet, "build_ext"]
    if force_rebuild:
        args.append("--force")
    if inplace and package_base_dir:
        args.extend(['--build-lib', package_base_dir])
        if ext.name == '__init__' or ext.name.endswith('.__init__'):
            # package => provide __path__ early
            if not hasattr(ext, 'cython_directives'):
                ext.cython_directives = {'set_initial_path': 'SOURCEFILE'}
            elif 'set_initial_path' not in ext.cython_directives:
                ext.cython_directives['set_initial_path'] = 'SOURCEFILE'

    if HAS_CYTHON and build_in_temp:
        args.append("--pyrex-c-in-temp")
    sargs = setup_args.copy()
    sargs.update({"script_name": None, "script_args": args + script_args})
    dist = Distribution(sargs)
    if not dist.ext_modules:
        dist.ext_modules = []
    dist.ext_modules.append(ext)
    if HAS_CYTHON:
        dist.cmdclass = {'build_ext': build_ext}
    build = dist.get_command_obj('build')
    build.build_base = pyxbuild_dir

    cfgfiles = dist.find_config_files()
    dist.parse_config_files(cfgfiles)

    try:
        ok = dist.parse_command_line()
    except DistutilsArgError:
        raise

    if DEBUG:
        print("options (after parsing command line):")
        dist.dump_option_dicts()
    assert ok

    try:
        obj_build_ext = dist.get_command_obj("build_ext")
        dist.run_commands()
        so_path = obj_build_ext.get_outputs()[0]
        if obj_build_ext.inplace:
            # Python distutils get_outputs()[ returns a wrong so_path
            # when --inplace ; see http://bugs.python.org/issue5977
            # workaround:
            so_path = os.path.join(os.path.dirname(filename),
                                   os.path.basename(so_path))
        if reload_support:
            org_path = so_path
            timestamp = os.path.getmtime(org_path)
            global _reloads
            last_timestamp, last_path, count = _reloads.get(
                org_path, (None, None, 0))
            if last_timestamp == timestamp:
                so_path = last_path
            else:
                basename = os.path.basename(org_path)
                while count < 100:
                    count += 1
                    r_path = os.path.join(obj_build_ext.build_lib,
                                          basename + '.reload%s' % count)
                    try:
                        import shutil  # late import / reload_support is: debugging
                        try:
                            # Try to unlink first --- if the .so file
                            # is mmapped by another process,
                            # overwriting its contents corrupts the
                            # loaded image (on Linux) and crashes the
                            # other process. On Windows, unlinking an
                            # open file just fails.
                            if os.path.isfile(r_path):
                                os.unlink(r_path)
                        except OSError:
                            continue
                        shutil.copy2(org_path, r_path)
                        so_path = r_path
                    except IOError:
                        continue
                    break
                else:
                    # used up all 100 slots
                    raise ImportError("reload count for %s reached maximum" %
                                      org_path)
                _reloads[org_path] = (timestamp, so_path, count)
        return so_path
    except KeyboardInterrupt:
        sys.exit(1)
    except (IOError, os.error):
        exc = sys.exc_info()[1]
        error = grok_environment_error(exc)

        if DEBUG:
            sys.stderr.write(error + "\n")
        raise
Example #22
0
def c_to_dll(filename, ext = None, force_rebuild = 0,
               build_in_temp=False, cbuild_dir=None, setup_args={},
               reload_support=False, inplace=False):
    """Compile a C file to a DLL and return the name of the generated .so 
       or .dll ."""
    assert os.path.exists(filename), "Could not find %s" % os.path.abspath(filename)

    path, name = os.path.split(os.path.abspath(filename))

    if not ext:
        modname, extension = os.path.splitext(name)
        assert extension in (".c", ".py"), extension
        if not HAS_CYTHON:
            filename = filename[:-len(extension)] + '.c'
        ext = Extension(name=modname, sources=[filename])

    if not cbuild_dir:
        cbuild_dir = os.path.join(path, "_cbld")

    package_base_dir = path
    for package_name in ext.name.split('.')[-2::-1]:
        package_base_dir, pname = os.path.split(package_base_dir)
        if pname != package_name:
            # something is wrong - package path doesn't match file path
            package_base_dir = None
            break

    script_args=setup_args.get("script_args",[])
    if DEBUG or "--verbose" in script_args:
        quiet = "--verbose"
    else:
        quiet = "--quiet"
    args = [quiet, "build_ext"]
    if force_rebuild:
        args.append("--force")
    if inplace and package_base_dir:
        args.extend(['--build-lib', package_base_dir])
        if ext.name == '__init__' or ext.name.endswith('.__init__'):
            # package => provide __path__ early
            if not hasattr(ext, 'cython_directives'):
                ext.cython_directives = {'set_initial_path' : 'SOURCEFILE'}
            elif 'set_initial_path' not in ext.cython_directives:
                ext.cython_directives['set_initial_path'] = 'SOURCEFILE'

    if HAS_CYTHON and build_in_temp:
        args.append("--pyrex-c-in-temp")
    sargs = setup_args.copy()
    sargs.update({
        "script_name": None,
        "script_args": args + script_args,
    })
    # late import, in case setuptools replaced it
    from distutils.dist import Distribution
    dist = Distribution(sargs)
    if not dist.ext_modules:
        dist.ext_modules = []
    dist.ext_modules.append(ext)
    if HAS_CYTHON:
        dist.cmdclass = {'build_ext': build_ext}
    build = dist.get_command_obj('build')
    build.build_base = cbuild_dir

    cfgfiles = dist.find_config_files()
    dist.parse_config_files(cfgfiles)

    try:
        ok = dist.parse_command_line()
    except DistutilsArgError:
        raise

    if DEBUG:
        print("options (after parsing command line):")
        dist.dump_option_dicts()
    assert ok


    try:
        obj_build_ext = dist.get_command_obj("build_ext")
        dist.run_commands()
        so_path = obj_build_ext.get_outputs()[0]
        if obj_build_ext.inplace:
            # Python distutils get_outputs()[ returns a wrong so_path 
            # when --inplace ; see http://bugs.python.org/issue5977
            # workaround:
            so_path = os.path.join(os.path.dirname(filename),
                                   os.path.basename(so_path))
        if reload_support:
            org_path = so_path
            timestamp = os.path.getmtime(org_path)
            global _reloads
            last_timestamp, last_path, count = _reloads.get(org_path, (None,None,0) )
            if last_timestamp == timestamp:
                so_path = last_path
            else:
                basename = os.path.basename(org_path)
                while count < 100:
                    count += 1
                    r_path = os.path.join(obj_build_ext.build_lib,
                                          basename + '.reload%s'%count)
                    try:
                        import shutil # late import / reload_support is: debugging
                        try:
                            # Try to unlink first --- if the .so file
                            # is mmapped by another process,
                            # overwriting its contents corrupts the
                            # loaded image (on Linux) and crashes the
                            # other process. On Windows, unlinking an
                            # open file just fails.
                            if os.path.isfile(r_path):
                                os.unlink(r_path)
                        except OSError:
                            continue
                        shutil.copy2(org_path, r_path)
                        so_path = r_path
                    except IOError:
                        continue
                    break
                else:
                    # used up all 100 slots 
                    raise ImportError("reload count for %s reached maximum"%org_path)
                _reloads[org_path]=(timestamp, so_path, count)
        return so_path
    except KeyboardInterrupt:
        sys.exit(1)
    except (IOError, os.error):
        exc = sys.exc_info()[1]
        error = grok_environment_error(exc)

        if DEBUG:
            sys.stderr.write(error + "\n")
        raise
Example #23
0
def distutils_scheme(
    dist_name: str,
    user: bool = False,
    home: str = None,
    root: str = None,
    isolated: bool = False,
    prefix: str = None,
    *,
    ignore_config_files: bool = False,
) -> Dict[str, str]:
    """
    Return a distutils install scheme
    """
    from distutils.dist import Distribution

    dist_args: Dict[str, Union[str, List[str]]] = {"name": dist_name}
    if isolated:
        dist_args["script_args"] = ["--no-user-cfg"]

    d = Distribution(dist_args)
    if not ignore_config_files:
        try:
            d.parse_config_files()
        except UnicodeDecodeError:
            # Typeshed does not include find_config_files() for some reason.
            paths = d.find_config_files()  # type: ignore
            logger.warning(
                "Ignore distutils configs in %s due to encoding errors.",
                ", ".join(os.path.basename(p) for p in paths),
            )
    obj: Optional[DistutilsCommand] = None
    obj = d.get_command_obj("install", create=True)
    assert obj is not None
    i = cast(distutils_install_command, obj)
    # NOTE: setting user or home has the side-effect of creating the home dir
    # or user base for installations during finalize_options()
    # ideally, we'd prefer a scheme class that has no side-effects.
    assert not (user and prefix), f"user={user} prefix={prefix}"
    assert not (home and prefix), f"home={home} prefix={prefix}"
    i.user = user or i.user
    if user or home:
        i.prefix = ""
    i.prefix = prefix or i.prefix
    i.home = home or i.home
    i.root = root or i.root
    i.finalize_options()

    scheme = {}
    for key in SCHEME_KEYS:
        scheme[key] = getattr(i, "install_" + key)

    # install_lib specified in setup.cfg should install *everything*
    # into there (i.e. it takes precedence over both purelib and
    # platlib).  Note, i.install_lib is *always* set after
    # finalize_options(); we only want to override here if the user
    # has explicitly requested it hence going back to the config
    if "install_lib" in d.get_option_dict("install"):
        scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib))

    if running_under_virtualenv():
        scheme["headers"] = os.path.join(
            i.prefix,
            "include",
            "site",
            f"python{get_major_minor_version()}",
            dist_name,
        )

        if root is not None:
            path_no_drive = os.path.splitdrive(
                os.path.abspath(scheme["headers"]))[1]
            scheme["headers"] = os.path.join(
                root,
                path_no_drive[1:],
            )

    return scheme