Kotlin cannot import packages - import

I'm using kotlin on command line and I'm getting import errors error: unresolved reference: ConnectionHandler
Following is my directory tree:
$ tree .
.
├── LICENSE
├── main.jar
├── main.kt
└── server
├── ConnectionHandler.class
├── ConnectionHandler.kt
├── HttpRequest.class
└── HttpRequest.kt
1 directory, 7 files
When I run kotlinc main.kt -include-runtime -d main.jar I get
main.kt:2:8: error: unresolved reference: server
import server.*
I have declared package server in both of server/ConnectionHandler.kt and server/HttpRequest.kt
Note: The META-INF folder is missing. It is not regenerated either on subsequent compilations.
What am I doing wrong? If it has anything to do with META-INF folder, how can I regenerate it?

You need to include all your source files when using kotlinc (or at least include the compiled classes on the classpath). e.g.
kotlinc main.kt server/ConnectionHandler.kt server/HttpRequest.kt -include-runtime -d main.jar

Related

Import File Mismatch in pytest with same test names

This is a much asked question, but none of the solutions mentioned on SO have worked so far.
The folder structure is as follows:
project/
└── tests/
├── conftest.py
├── __init__.py
└── int_tests/
└── test_device.py
└── project_core/
└── tests/
├── conftest.py
├── __init__.py
└── int_tests/
└── test_device.py
import file mismatch:
imported module 'test_device' has this __file__ attribute:
/home/.../project/project_core/tests/int_tests/test_device.py
which is not the same as the test file we want to collect:
/home/.../project/tests/int_tests/test_device.py
HINT: remove __pycache__ / .pyc files and/or use a unique basename for your test file modules
Steps tried so far:
Removing pycache and pyc files.
Adding _init to each folder. (As is stated in pytest GIP)
Removing _init from each folder.
Do i need init files in each tests/subfolder?
The same error occurs with conftest.py as well. This error is not limited to vscode-pytest plugin, also occurs on the terminal.
PS : For CI purposes, the system is configured with docker & tox. Development is done in venv.

Customizing python package directory layout with setup.py

Suppose I have the following directory structure:
src/
└── python/
└── generated/
├── __init__.py
├── a.py
└── lib/
├── __init__.py
└── b.py
What does my setup.py need to look like in order to create a dist with a directory layout like:
src/
└── python/
├── __init__.py
├── a.py
└── lib/
├── __init__.py
└── b.py
The goal is to simply eliminate the generated folder. I've tried endless variations with package_dir and can't get anything produced other than the original directory structure.
Your setup.py should be placed in your src directory and should look like this:
#!/usr/bin/env python3
import setuptools
setuptools.setup(
name='Thing',
version='1.2.3',
packages=[
'python',
'python.lib',
],
package_dir={
'python': 'python/generated',
},
)
Note the package_dir setting. It instructs setuptools to get the code for the python package from the directory python/generated. In the built distributions you will then find the right directory structure.
First, here is my solution:
#!/usr/bin/env python
import os, shutil
from setuptools import setup
from setuptools.command.build_py import build_py
class BuildPyCommand(build_py):
"""Custom build command."""
def run(self):
shutil.rmtree('src.tmp', ignore_errors=True)
os.mkdir('src.tmp')
shutil.copytree('src/python/generated', 'src.tmp/python')
build_py.run(self)
setup(cmdclass={ 'build_py': BuildPyCommand },
name='Blabla',
version='1.0',
description='best desc ever',
author='Me',
packages=['python', 'python.lib'],
package_dir={'': 'src.tmp'},
setup_requires=['wheel']
)
And you can generate your distribution with:
python setup.py build bdist_wheel
The idea is perform a two steps build:
I generate a valid source structure
I build this temporary structure
And I deliver it in a wheel because it doesn't require future users to understand my trick. If you give it a try with a source distribution, you will notice that you need to publish the generated files as data (not difficult, but troublesome, and, I guess you will want to hide your tricks from your users).
But, I think that there is a design flaw in your process. The file src/python/generated/__init__.py, assumed to be a module <something>.generated eventually becomes your <something>.python, which is troublesome. It would be much simpler and more robust to generate a valid Python structure: src/generated/python/__init__.py. The setup.py would become trivial and your generator wouldn't be more complex.

What is the simplest way to create an importable file in Scala?

TLDR: What is the simplest way to create an importable file in Scala?
This is a beginner's question.
I've been learning Scala for a few weeks and now have some code that I would like to share between a couple of files/different projects. I have tried a lot of import structures but none of them worked. The requirements are:
File to be imported should reside in a totally different directory.
File to be imported should be importable by independent projects.
File to be imported is a single .scala file.
(Optional) file to be imported should contain defs, objects and case classes.
Example:
File to be imported location: /some/path/to_be_imported.scala.
File using project (1) location: /abc/def/will_import01.scala.
File using project (2) location: /xyz/rst/will_import02.scala.
I'm not trying to create a package or distribute it.
See how I would address this considering the programming language I already know:
Since I'm versed in Python I'll give an expected version of the answer should this problem refer o Python:
In that case you could:
Put your file on the same directory of your executed file then just run: python3 ./your_file.py. For instance:
➜ another_path|$ python3 ./main_module/main_file.py
1
self printing
➜ another_path|$ tree .
=======================================================================
.
└── main_module
├── main_file.py
├── __pycache__
│   └── sample_file_to_be_imported.cpython-36.pyc
└── sample_file_to_be_imported.py
Notice that they are in the exact same directory (this contradicts point 2 above nevertheless it solves the problem).
Add the directory of your file to the PYTHONPATH environment variable then run your module (best answer):
➜ random_path|$ PYTHONPATH=$PYTHONPATH:./sample_module python3 ./main_module/main_file.py
1
self printing
=======================================================================
➜ random_path|$ tree .
.
├── main_module
│   └── main_file.py
└── sample_module
├── __pycache__
│   └── sample_file_to_be_imported.cpython-36.pyc
└── sample_file_to_be_imported.py
3 directories, 3 files
Content of the files:
➜ random_path|$ cat ./main_module/main_file.py
from sample_file_to_be_imported import func1, Class01
print(func1())
x = Class01()
x.cprint()
=======================================================================
➜ random_path|$ cat ./sample_module/sample_file_to_be_imported.py
def func1():
return 1
class Class01():
def cprint(self):
print('self printing')
Edit 01: #felipe-rubin answer does not work:
$ scala -cp /tmp/scala_stack_exchange/ myprogram.scala
/tmp/scala_stack_exchange/path01/myprogram.scala:3: error: not found: value Timer
val x = Timer(1)
^
one error found
=======================================================================
➜ path01 tree /tmp/scala_stack_exchange
/tmp/scala_stack_exchange
├── anotherpath
│   ├── Timer.class
│   └── timer.scala
└── path01
└── myprogram.scala
2 directories, 3 files
=======================================================================
$ cat /tmp/scala_stack_exchange/anotherpath/timer.scala
class Timer(a: Int) {
def time(): Unit = println("time this")
}
=======================================================================
$ cat /tmp/scala_stack_exchange/path01/myprogram.scala
import anotherpath.Timer
val x = Timer(1)
x.time()
The simplest way would be to compile a .scala file with scalac:
Linux/OSX: scalac mypackage/Example.scala
Windows: scalac mypackage\Example.scala
The above should generate a .class file (or more).
Assuming the file contains a class called Example you can import it somewhere else like this:
import mypackage.Example
When compiling another file which does the above import, you will need to have 'mypackage' in the classpath. You can add directories to the classpath when calling scalac by using the -cp flag like:
Linux/OSX: scalac -cp .:path/to/folder/where/mypackage/is/located AnotherExample.scala
Windows: scalac -cp .;path\to\folder\where\mypackage\is\located AnotherExample.scala
Doing this for bigger projects gets complicated, in which case you might resort to a build tool (e.g. SBT) or an IDE (e.g. IntelliJ Idea) to do the complicated work for you.
Other notes:
If you don't have scalac, you can get it from the scala website ('download binaries' option)
the -cp flag stand for "classpath". There is also a -classpath flag which does the same thing
Welcome to Scala :)
I finally got this working. Thanks for the valuable input from the other answers.
I have diversified the name of every path, file and object to be as general as possible. This probably does not follow the guidelines of the scala community but is the most explicit, illustrative help I could find. Project layout:
File Layout
$ tree /tmp/scala_stack_exchange
/tmp/scala_stack_exchange
├── anotherpath
│   ├── file_defines_class.scala
│   └── some_package_name
│   ├── MyObj.class
│   └── MyObj$.class
└── path01
└── myprogram.scala
3 directories, 4 files
Where I want to run myprogram.scala which should import classes defined in file_defines_class.scala.
Preparation
Compile the file you want to be imported by other modules:
cd /tmp/scala_stack_exchange/anotherpath && scalac ./file_defines_class.scala
Execution
cd /tmp/scala_stack_exchange/path01 && scala -cp /tmp/scala_stack_exchange/anotherpath/ ./myprogram.scala
Results
myobj time
Contents of the files
// /tmp/scala_stack_exchange/path01/myprogram.scala
import some_package_name.MyObj
val x = new MyObj(10)
x.time()
// /tmp/scala_stack_exchange/anotherpath/file_defines_class.scala
package some_package_name
object MyObj
case class MyObj(i: Int) {
def time(): Unit = println("myobj time")
}
Feels like magic. However this whole process is rather cumbersome :/

setuptools sdist ignore data_files

According to docs https://packaging.python.org/en/latest/distributing/#data-files
setuptools will honor data_files configed in setup.py. But i can't make it work. This is my setup.py:
setup(
name='booking_order',
version=version,
packages=find_packages(),
package_data={
'booking_order': ['fake_backends/static/*',
'scripts/*',
'*.sample'],
},
data_files=[
('/etc/booking', ['etc/booking.conf'])
],
This is the project's file tree:
.
├── booking_order
│   ├── __init__.py
│   ├── tests
│   │   ├── __init__.py
├── etc
│   ├── booking.conf
├── README.md
├── setup.py
The behavior is, if i run python setup.py install, file etc/booking.conf will got installed to /etc/booking. But if i first python setup.py sdist upload, then pip install booking_order, there will be an error "error: can't copy 'etc/booking.conf': doesn't exist or not a regular file".
I checked python setup.py sdist doesn't include files in etc at all.
EDIT:
it seems this is the answer: https://github.com/pypa/setuptools/issues/521
Answer it myself.
According to pypa, and non-package-data-files。"Setuptools doesn't support installing data files to some arbitrary location on a user’s machine; this is a feature, not a bug."
If one need to install files to locations like /etc, /usr/share, eg, then he/she may use data_files flag from distutils, which feature is not totally cleaned up from setuptools. "Not totally cleaned up" means you need to add those files to MANIFEST.in manually, which is different as in distutils.
Of course, it will be better if one can manage these configuration files with rpm or deb package system. For me it's just a temporary solution to use pip here.

CPACK embed text files

I want to distribute a gzipped tarball containing a program binary.
No problem making a package containing the binary plus additional script/man files because these are files I install with CMake INSTALL command during a source installation.
While the need for such a functionality seems quite obvious to me, I didn't find a way to include text files in CPack tarball packages.
Here is an example of the final tarball I'd like to get:
myprogram-1.0.0rc-Darwin-i386/
├── LICENSE <- not installed by CMake
├── INSTALL <- not installed by CMake
├── README <- not installed by CMake
├── bin
│   └── myprogram
└── share
└── myprogram
└── man
   └── man1
    └── myprogram.1
Any help would be very much appreciated.
Cheers
You can use install too with FILES or DIRECTORY option.
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.txt DESTINATION .)